# ZFG **Official meaning:** `Zero Friction Growth` **Unofficial meaning:** `Zero Fucks Given` ## Z — Zero Friction Architecture should make growth easy. Adding new modules, services, tenants, integrations, or developers should not require rewriting half of the system. ### Principles - Modular architecture - Low coupling - Clear interfaces - Easy onboarding - Predictable project structure - Minimal friction when adding new functionality --- ## F — Flexible Foundations The core infrastructure should stay generic, reusable, and extensible. Business-specific logic should sit on top of the foundation instead of contaminating it. ### Core building blocks - Authentication - Authorization - Roles & permissions - Organizations - Events - Workflows - Storage - Notifications - API layer - Integrations - Configuration ### Principles - Reusable core - Configuration-driven behavior - Extensible modules - Replaceable infrastructure - Clear separation between core and business logic --- ## G — Growth-Ready The system should be designed to scale in multiple dimensions. Not only more traffic, but also more customers, data, modules, developers, integrations, and services. ### Principles - Horizontal scaling - Multi-tenancy - Async processing - Observability - Independent modules - Independent deployment paths where needed - Efficient data growth - Clear service boundaries --- ## Philosophy ```text ZFG │ ├── Z — Zero Friction │ ├── modular architecture │ ├── low coupling │ ├── clear interfaces │ └── easy onboarding │ ├── F — Flexible Foundations │ ├── reusable core │ ├── configuration-driven behavior │ ├── extensible modules │ └── replaceable infrastructure │ └── G — Growth-Ready ├── horizontal scaling ├── multi-tenancy ├── async processing ├── observability └── independent deployment paths ``` ## Motto > **Build with Zero Friction. Stay Flexible. Be Growth-Ready.** Or, internally: > **Zero Fucks Given.** ## About | App | Source | Dev port | What it is | | --------------- | --------------- | -------- | ------------------------------------------------------ | | Backend API | `apps/backend/` | 3333 | AdonisJS — data, auth, permissions, public content API | | Admin panel | `apps/admin/` | 5173 | React + Vite — the internal UI | | Public website | `apps/web/` | 3000 | Next.js — the site visitors see | | Shared packages | `packages/` | — | UI, hooks, services, types, utils | Full documentation lives in [`docs/`](./docs/Readme.md). ### Tech Stack #### Backend - AdonisJS - TypeScript - Lucid ORM - PostgreSQL / MySQL (configurable) - Redis, S3 / MinIO storage #### Admin panel - React - TypeScript - Vite - React Query / MobX / Axios - Radix UI + Tailwind component system - React Hook Form + Zod #### Public website - Next.js (App Router, React Server Components) - TypeScript - next-intl - Tailwind CSS ### Getting Started #### Prerequisites - Node.js `24.18.0` (see `.nvmrc`; the package manifest requires `>=24.0.0`) - npm `>=11.6.2` (the repo pins `npm@11.15.0`) - PostgreSQL #### Installation ```bash git clone https://git.kossmc.com/coach.one1994/zero-fucks-given.git ``` ```bash cd zero-fucks-given && npm install --force ``` > `--force` is required. `typescript-eslint` does not yet declare support for the TypeScript > version this repo uses, so a plain `npm install` fails with `ERESOLVE`. Never substitute > `--legacy-peer-deps` — it strips nested peer dependencies and breaks the backend at runtime. Use > `npm ci --force` for a reproducible install, and `npm install --force` when adding one. > See [troubleshooting.md](./troubleshooting.md). ### Configuration Each workspace defines its own environment variables. Copy the workspace's `.env.example` to `.env` and fill in the values: | Env file | Covers | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `apps/backend/.env` | Server (`PORT`, `APP_KEY`), database (`DB_*`), storage (`AWS_*`, `S3_*`), and the public site link (`WEB_APP_URL`, `WEB_REVALIDATE_SECRET`) used to purge its cache | | `apps/admin/.env` | `VITE_API_URL` (backend), `VITE_WEB_URL` (public site, used for page previews), `VITE_TINYMCE_API_KEY` | | `apps/web/.env` | `BACKEND_API_URL` (backend base URL for server rendering), `REVALIDATE_SECRET` (must match the backend's `WEB_REVALIDATE_SECRET`), `SITE_URL` (canonical origin) | `docker-compose.yml` loads each service's env from the same per-app files. Inside Docker, service URLs must use compose service names (`http://backend:3333`), not `localhost`. ### Running #### Locally | Command | Description | | ----------------------- | ----------------------------------------------- | | `npm run dev:backend` | Start the AdonisJS backend in development mode | | `npm run dev:admin-app` | Start the React admin application | | `npm run dev:web` | Start the Next.js web application | | `npm run dev:all` | Start backend, admin, and web apps concurrently | #### With Docker ```bash docker compose up -d ``` Brings up everything: backend (3333), admin (5173), web (3000), PostgreSQL (5432), Redis (6379), MinIO (9000 / console 9001) and pgAdmin (5050). Two quirks worth knowing when a change appears not to take effect: - The web container keeps `.next` on an anonymous volume that survives rebuilds. Clear it with `docker compose up -d --force-recreate --renew-anon-volumes web`. - Backend HMR does not always pick up edits on macOS (bind-mount file events); restart `crux_backend_adonis` to load them. ### Scripts #### Build | Command | Description | | ----------------------- | ------------------------------------------ | | `npm run build:backend` | Build the backend application | | `npm run build:admin` | Type-check and build the admin application | | `npm run build:web` | Type-check and build the Next.js web app | #### Test | Command | Description | | ---------------------- | ---------------------------------------------- | | `npm run test:backend` | Backend functional tests (requires a database) | | `npm run test:admin` | Admin unit tests (Vitest) | | `npm run test:web` | Web app unit tests (Vitest) | #### Lint and format | Command | Description | | ---------------------- | -------------------------- | | `npm run lint` | ESLint across the monorepo | | `npm run lint:fix` | ESLint with autofix | | `npm run format` | Prettier write | | `npm run format:check` | Prettier check, no writes | #### Versions | Command | Description | | ----------------------- | ------------------------------------ | | `npm run version:patch` | Update patch version of all packages | | `npm run version:minor` | Update minor version of all packages | | `npm run version:major` | Update major version of all packages | > Versions are updated without creating git tags. ### Features #### Module Generator Create full CRUD modules by selecting: - Database table - Fields and types - Validation rules - List view configuration **Generated output** — Backend: controllers, validators, routes. Frontend: pages, forms, tables, API. #### Authentication & Authorization - JWT / session-based authentication - Role & permission system - Policy-based access control #### Content Management Web Manager is the built-in CMS: editors build localized pages from prebuilt blocks in the admin panel, preview them privately, and publish to the Next.js site, which purges only the cache entries the change affects. See [Web Manager](./docs/core/web-manager/Readme.md). ### Documentation | Topic | Where | | ------------------------ | ---------------------------------------------------- | | Documentation home | [docs/Readme.md](./docs/Readme.md) | | Public website | [apps/web/Readme.md](./apps/web/Readme.md) | | Architecture | [docs/architecture/](./docs/architecture/Readme.md) | | Core modules | [docs/core/](./docs/Readme.md#core-modules) | | Shared packages | [docs/packages/Readme.md](./docs/packages/Readme.md) | | Install and setup issues | [troubleshooting.md](./troubleshooting.md) |