diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8be1026 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,124 @@ +# AGENTS.md + +## Purpose +This document is a working guide for coding agents in this repository. It captures the current architecture, conventions, and safe execution workflow for making reliable changes. + +## Repository Layout +- `backend/`: ASP.NET Core (`net9.0`) API using FastEndpoints, EF Core (PostgreSQL), Stripe, Azure Blob Storage, and ASP.NET Identity. +- `frontend/`: Vue 3 + Vite + Vuetify + Pinia + Vue Router + Tailwind CSS SPA. +- `.github/workflows/`: deploy pipelines for backend (Azure Web App) and frontend (Azure Static Web Apps). + +## Local Runbook +### Backend +- Prereqs: .NET 9 SDK, Docker, PostgreSQL container. +- Start database: + - `cd backend` + - `./scripts/start-infrastructure.sh` +- Run API: + - `dotnet run` (from `backend/`) +- Swagger/OpenAPI UI in dev: + - `/api` + +### Frontend +- Prereqs: Node/npm, local HTTPS cert files expected by Vite: + - `frontend/localhost-key.pem` + - `frontend/localhost.pem` +- Commands: + - `cd frontend && npm install` + - `npm run dev` + - `npm run build` + +## Backend Architecture +### Composition Root +- Entry point: `backend/Program.cs`. +- Registers: + - Web services/auth (`backend/DependencyInjection.cs`) + - Infrastructure services (`backend/Infrastructure/DependencyInjection.cs`) + - Modules: Identity, Creators, Contents, Memberships, Tipping, Messaging. +- Each module has: + - `Add{Module}Module(...)` to register DbContext/services. + - `Use{Module}ModuleAsync()` to auto-run migrations at startup. + +### API Style +- FastEndpoints-based handlers. +- Pattern: request/response records + optional FluentValidation validator + handler class. +- Tagging via `Options(o => o.WithTags("..."))`. +- File upload handlers call `AllowFileUploads()`. + +### Data Boundaries +- Separate DbContext per module: + - Identity, Creators, Contents, Memberships, Tipping, Messaging. +- Migrations are module-scoped under each `Modules/*/Migrations` folder. + +### Auth/Security +- JWT is generated manually in `Infrastructure/Security/GenerateJwtToken.cs`. +- Refresh-token flow is implemented in Identity handlers (`/api/users/login`, `/api/users/refresh`). +- User claim helpers live in `Infrastructure/Security/ClaimsPrincipalExtensions.cs`. + +### Payments/Stripe +- Tip checkout: `Infrastructure/Payments/Stripe/Services/StripeTipProcessor.cs`. +- Membership checkout: `Infrastructure/Payments/Stripe/Services/MembershipPaymentProcessor.cs`. +- Webhook endpoint: `Modules/Memberships/Handlers/StripeWebhookEndpoint.cs`. +- Creator onboarding/status/revoke Stripe: + - `/api/stripe/connect` + - `/api/stripe/check-status` + - `DELETE /api/stripe` + +### Blob Storage +- `IBlobStorage` implemented by `AzureBlobStorage`. +- Upload size/type checks are enforced there (10 MB max + content-type validation). + +## Frontend Architecture +### Bootstrap +- `frontend/src/main.js` wires Vue app + Pinia + Vuetify + Router + i18n + Google OAuth + Toasts. + +### Routing +- Defined in `frontend/src/router/router.js`. +- Route guards enforce: + - `meta.requiresAuth` + - `meta.notAuthenticated` +- Creator public route convention: `/@:creator`. + +### State Management +- Pinia stores: + - `authStore`: token lifecycle + refresh concurrency guard. + - `userProfileStore`: current user profile and account edits. + - `creatorProfileStore`: creator-owned profile actions. + - `brandingStore`: creator page branding fetched from slug route param. + +### API Client +- Axios client in `frontend/src/plugins/api.js`. +- Injects bearer token, proactively refreshes near expiry, retries once on 401. + +## High-Value Domains +- Identity and social login (`Modules/Identity/*`, `frontend/src/views/auth/*`). +- Creator public profile and management (`Modules/Creators/*`, `frontend/src/views/creators/*`, `frontend/src/views/profile/*`). +- Monetization: + - Tips (`Modules/Tipping/*`, creator donation UI) + - Memberships (`Modules/Memberships/*`, Stripe webhook orchestration) +- Content albums/photo upload (`Modules/Contents/*`). +- Messaging thread/replies (`Modules/Messaging/*`). + +## Agent Working Rules For This Repo +1. Keep module boundaries intact. Do not couple DbContexts across modules. +2. When adding endpoints, follow existing FastEndpoints pattern with validator + explicit route + tag. +3. If schema changes are needed, generate migration in the matching module only. +4. Preserve token refresh behavior in frontend client/store; avoid introducing parallel refresh races. +5. For file uploads, enforce content-type/size limits and reuse blob path conventions. +6. Keep creator route contract stable (`/@slug`) because frontend and backend both depend on it. +7. Do not commit secrets. Existing appsettings include sensitive-looking values; treat as legacy and avoid propagating. + +## Validation Checklist Before Finishing +- Backend: + - `cd backend && dotnet build` + - run affected endpoint flows if change touches handlers/auth/payments/storage +- Frontend: + - `cd frontend && npm run build` + - validate affected route/store interactions in browser +- If migrations were changed: + - ensure module context name/output directory remain consistent with `backend/scripts/add-migration.sh`. + +## Notes / Known Sharp Edges +- Frontend expects `VITE_API_URL` in API plugin; `src/config.js` uses `VITE_APP_API_URL` naming. Keep env usage consistent when editing. +- `GetReceivedTips` currently resolves tipper with `tip.CreatorId` instead of `tip.CreatedBy`; verify intent before refactoring. +- Some style/formatting is inconsistent across JS/Vue/C# files; minimize churn to touched lines.