Rebrand Audit
Pracino → Parino:
What's Left
Every user-visible "Pracino" is now "Parino" across the landing page, the mobile app, and API email. This is the complete inventory of what still says pracino, why each one was left, and what breaks if someone changes it anyway.
01Summary
Three commits on feature/196-update-pracino-parino-na-lp-v-appce. Copy is done; every remaining mention is an identifier, infrastructure, a test fixture, or documentation.
- All product copy is renamed. LP, in-app strings, permission prompts, app display name, and every transactional email in both
csanden. - No identifier was renamed. Bundle IDs, package names, store product IDs, storage keys, DB name, and the S3 bucket are untouched by design — they are contracts with Apple, Google, Firebase, and existing installs.
- The share-link domain moved to
parino.cz. This is native config: it needs a rebuild, not an OTA push. - Czech declension nearly cost us two strings. See the next section — this is the one finding worth reading even if you skip everything else.
02The declension trap
A grep for 'pracino' does not find 'Pracinu'. Czech inflects the brand name, and it hid two strings in a file that looked clean.
Pracino is a Czech neuter noun and it declines. The locative is v Pracinu, not v Pracino.
Every grep run during this audit searched for the string pracino — so it reported
apps/api/src/i18n/cs/emails/auth.json as having zero brand mentions. It had two:
"subject": "Vítej v Pracinu"
"body_primary": "vítej v Pracinu. Vyplň si profil a my z něj připravíme..."This only surfaced because the emails were rendered and their subjects printed. Six
declined mentions were found this way, all in the API, all now v Parinu.
Search the stem pracin, never the full word pracino. The forms to expect are Pracina (gen.), Pracinu (dat./loc.), Pracinem (instr.). The same applies to Parino → v Parinu, which is what the strings now say.
The mobile app and LP had no declined forms — Czech copy there phrases around the
nominative (aplikaci Parino, Stáhni si Parino). The API was the only place that
inflected it.
03Mobile
174 stem hits remain in apps/mobile. All are identifiers, fixtures, or tracker references — no user-visible text.
| What | Where | Tied to | If changed |
|---|---|---|---|
| `com.pracino.app` | `app.config.js:6` (+ 9 refs) | The bundle ID / Android package. Google OAuth and Maps API keys are registered against package + SHA-1; Apple Sign-In is keyed to it. | OAuth, Google Maps, and Apple Sign-In all break. On Android a package rename is a new app — no upgrade path for installs. |
| `@pracino/*` imports | 104 refs | Workspace package names (`@pracino/api-client`). | Nothing user-visible. Mechanical but noisy; do it with the monorepo rename, not piecemeal. |
| `com.pracino.mobile.prototype` | 43 refs in `.maestro/` + specs | The *old* prototype scheme. Already stale — the real bundle is `com.pracino.app`. | Pre-existing drift, unrelated to the rebrand. The Maestro `appId` almost certainly doesn't match the installed app already. |
| `pracino.auth.session` | `features/auth/constants/storage-keys.ts:1` | AsyncStorage key holding the live session. | **Every user is silently logged out on update.** The app reads the new key, finds nothing, and treats them as signed out. |
| `pracino.companyMemberRemoved.notice` | `features/auth/constants/storage-keys.ts:2` | AsyncStorage key for a pending notice. | A queued notice is dropped. Minor, but same class of bug. |
| `pracino.push.deviceId` | `features/notifications/constants/push-device-storage-keys.ts:1` | AsyncStorage key for the push device id. | Device re-registers; possible duplicate push registrations server-side. |
| `slug: "pracino"` | `app.config.js:152` | The EAS project slug — identity of the project on Expo's servers. | Breaks the link to the EAS project (builds, updates, submissions). |
| `project_id: "pracino"` | `google-services.json:4-5` | The Firebase project + storage bucket. | This file is generated by Firebase. Editing it by hand desyncs from the console and breaks FCM push. |
| `pracino-ei5.2`, `pracino-mwn.3`, … | 5 code comments | Beads issue IDs — the tracker's own prefix, not the brand. | Breaks the reference to real tracked issues. Leave permanently. |
| `"Pracino s.r.o."`, `name: "Pracino"` | `use-company-profile-form.spec.ts`, `deep-link.spec.ts` | Test fixtures. The company-name ones represent a *tenant company*, not our brand. | Nothing — values are arbitrary and not asserted on. |
| "the pracino accents" | `ui/app-toast.tsx:37` (comment) | A prose comment about the accent colours. | Nothing. Cosmetic. |
Of everything on this page, pracino.auth.session is the one that looks trivial and isn't. It's a string in a constants file with no obvious blast radius — and renaming it logs out the entire installed base with no migration. If it ever moves, it needs a read-old-write-new fallback shipped at least one release ahead.
04Backend / API
60 stem hits remain in apps/api. All email and notification copy is renamed; what's left is env, product IDs, seeds, and fixtures.
All 13 i18n brand strings plus 6 declined Czech forms are renamed, in cs and en. The shared email layout was renamed to parino-email-layout.ts and all 7 templates updated. Verified by rendering all 8 emails in both locales.
| What | Where | Tied to | If changed |
|---|---|---|---|
| `pracino.contacts.10/25/50`, `pracino.job_posting.monthly` | `payments/constants/payment-product-catalog.ts` (+ 4 DTO examples), 22 refs | In-app purchase product IDs registered in App Store Connect / Play Console. | **Purchases break.** Apple product IDs are permanent once created — they cannot be reused or deleted. Android is confirmed not yet registered; iOS is unconfirmed (the PM may have created them during the payments work). |
| `DB_NAME=pracino` | `.env.example:7`, `.env.test.example:7` | The Postgres database name. | Needs a real DB migration/rename in every environment. Example file alone changes nothing. |
| `PAYLOAD_S3_BUCKET=pracino` | `.env.example:37` | The MinIO / S3 bucket holding uploaded files. | Every stored file URL breaks unless the bucket is migrated and existing URLs rewritten. |
| `api.pracino.cz`, `app.pracino.cz` | `.env.example:26,57` | Play webhook audience + company-invitation accept URL base. | Unknown whether `parino.cz` equivalents exist — only the apex was probed and it is live. **Needs confirmation before touching.** |
| `MAIL_FROM="info@pracino.cz"` | `.env.example:47` | Example sender address. | Nothing directly — the real value comes from deployed env. The in-code default is already `Parino <no-reply@parino.local>`. |
| `com.pracino.app` | `.env.example:12-14,22` | Apple client / IAP bundle ID and Play package name given to the API. | Must always match the mobile bundle ID. Change only together with mobile. |
| `@pracino.dev`, `@pracino.test` | 6 refs in `scripts/seed-*.cjs` | Generated seed email addresses. | Nothing. Local dev data only. |
| `"Pracino"`, `"Pracino s.r.o."` | `remove-company-member-use-case.spec.ts`, e2e specs, `test/helpers/company-seeds.ts` | Test fixtures for a *tenant company* name. | Nothing — arbitrary fixture values. |
| `getBucket: () => "pracino"` | `upload-file-use-case.spec.ts:31` | Mocked bucket name in a unit test. | Nothing, as long as it matches whatever the real bucket is called. |
| `app.pracino.local` | `test/email-previews/…:35,107` | Fixture URL in the email preview. | Nothing. Local fixture. |
The two decisions that actually need a backend owner: (1) whether the iOS IAP product IDs are already registered in App Store Connect — if not, renaming them to parino.* is free right now and permanently expensive later; (2) whether api.parino.cz / app.parino.cz exist yet. Everything else on this list is safe to leave indefinitely.
05Web / LP
3 stem hits remain. The landing page itself is fully renamed and verified.
| What | Where | Tied to | If changed |
|---|---|---|---|
| `455886FF53.com.pracino.app` | `public/.well-known/apple-app-site-association:5` | The iOS app ID claiming universal links for this domain. | Universal links stop resolving to the app. Must match the real bundle ID — which is unchanged, so this is **correct as-is**. |
| `com.pracino.app` | `public/.well-known/assetlinks.json:6` | The Android package claiming app links for this domain. | Same — must track the bundle ID, so leave it. |
| `"name": "@pracino/web"` | `package.json:2` | Workspace package name. | Nothing user-visible. |
assetlinks.json still carries a literal <PLAY_APP_SIGNING_SHA256> placeholder next to the real debug fingerprint. Confirmed acceptable — the app isn't on either store yet. It will need the real Play signing fingerprint before Android app links verify in a production build.
06Monorepo root & shared packages
Naming of the workspace itself. All cosmetic, all interlocking — a single mechanical change if it's ever wanted.
| What | Where | Tied to | If changed |
|---|---|---|---|
| `"name": "pracino"` | `package.json:2` | Root workspace name. | Nothing user-visible. |
| `@pracino/api`, `@pracino/web`, `@pracino/api-client`, `@pracino/mobile-prototype` | root `package.json` scripts, each workspace's `package.json` | Workspace package names, referenced by every `-w @pracino/…` script and ~105 imports. | Nothing user-visible, but it's all-or-nothing: rename a package without its imports and scripts and the build stops. |
| `APP_NAME: "pracino"` | `.gitlab-ci.yml:2` | CI variable, likely feeding image/deploy naming. | Could break deploy targets. Needs a CI owner to confirm. |
| `pracino_network`, `POSTGRES_DB: pracino`, bucket `local/pracino` | `docker-compose.yml.example` | Local dev stack naming. | Local only. Would need every dev to recreate containers/volumes. |
| `CREATE DATABASE pracino_test;` | `docker/postgres/initdb/01-create-test-database.sql:1` | Test DB bootstrap. The e2e harness asserts the DB name contains "test". | Must stay in sync with `.env.test`'s `DB_NAME`. |
07Docs
44 stem hits. Zero code impact — but one of them is a design token name that reads like code and isn't.
| What | Where | Tied to | If changed |
|---|---|---|---|
| `pracino-green`, `pracino-green-light` | `DESIGN.md` (29), `.impeccable/design.json` (12) | Design **token names**. Confirmed referenced nowhere in `apps/` or `packages/` — the code writes `primary: "#00C9A7"` directly. | Nothing. Documentation-only rename, zero code risk. |
| Full LP copy | `docs/landing/final/` — `index.html` (16), `app-link.html` (7), own `pracino.svg`, `styles.css`, `.well-known/` | A standalone static copy of the landing page — the original that `apps/web` was ported from. | Nothing live. **But it is now stale**: it still says Pracino while the deployed LP says Parino. Worth deleting or marking superseded so nobody ports from it again. |
| `/srv/pracino-landing`, `pm get-app-links com.pracino.app` | `docs/landing/DEPLOY.md:26,44,73` | Deploy paths and a debug command in the deploy runbook. | Nothing, but the runbook drifts from reality if the server path changes. |
| Prose mentions | `PRODUCT.md` (3), `README.md`, `PROJECT_MANIFEST.md`, `AGENTS.md`, `docs/mobile/design-language-template.md` (11) | Narrative brand references. | Nothing. Rename whenever convenient. |
docs/landing/final/ is a complete second copy of the landing page that no longer matches production. It's the highest-value cleanup on this page precisely because it looks authoritative and isn't.
08Excluded from this audit
Two areas were deliberately not touched.
| Area | Hits | Why excluded |
|---|---|---|
| `apps/mobile-prototype` | 19 | Reference-only per the project's own CLAUDE.md — not production, not shipped. Renaming it has no user impact and risks confusing it with the real app. |
| `core/` submodule | 1 — `packages/mobile/app.config.ts.example:30` (`com.pracino.mobile.prototype`) | Separate repo (`atreo/core`), shared across Atreo projects. Changes must land in core first, then the parent pointer bumps. It's a stale example file referencing the old prototype package — cosmetic, and not ours to change from here. |
09What actually shipped
Three commits, each independently verified.
- apps
- web
- public
- parino.svgwas pracino.svg; gradient id renamed with it
- src
- app
- layout.tsxtitles, description, metadataBase → parino.cz
- features
- landinghero, closing, header, footer, CTA, audience copy + wordmark
- app
- public
- mobile
- app.config.jsname, icon, permissions, shareLinkDomain, FB displayName
- assets
- images
- parino.pngapp icon
- images
- src
- i18n
- translations
- cs.json4 brand strings
- translations
- i18n
- api
- src
- modules
- mailing
- templates
- parino-email-layout.tswas pracino-email-layout.ts; wordmark, logo, footer, symbols
- templates
- mailing
- i18n13 strings + 6 declined Czech forms, cs & en
- modules
- src
- web
10Verification
What was actually exercised, not just typechecked.
- Web production build succeeds; static export contains zero
pracinooutside.well-known/ - All 3
<img src>refs in the exported HTML resolve to the renamedparino.svg - Mobile lint, format, and typecheck clean; 77 tests pass
- Resolved
app.config.jsverified:applinks:parino.cz, both Android intent filters onparino.cz, bundle + slug untouched parino.czconfirmed serving a live AASA identical to the old atreo host, with matching appIDs- All 8 transactional emails rendered in
cs+en; clean on a stem check (pracin), not justpracino - API typecheck adds no new errors (4 pre-existing failures confirmed present on the clean tree)
- Universal links re-verified on a device after a native rebuild —
shareLinkDomainis native config, so installed builds still resolve the old domain until rebuilt - iOS spot-check of the renamed app icon and home-screen name
The share-domain change doesn't take effect over-the-air. Existing installs keep claiming pracino.atreo.cz until they get a rebuilt binary, so that host should stay alive until the new build is out.