From 143b441d0c01e4608494f92419d7f0baa0bbbd44 Mon Sep 17 00:00:00 2001 From: MOH Date: Sat, 14 Mar 2026 13:29:32 +0100 Subject: [PATCH] docs: add project documentation and initial specs --- docs/ARCHITECTURE.md | 211 +++++++++++++++++++++++++++++++++++++++ docs/DOMAIN_RULES.md | 92 +++++++++++++++++ docs/FEATURES.md | 63 ++++++++++++ docs/PROJECT_OVERVIEW.md | 138 +++++++++++++++++++++++++ specs/admin.md | 48 +++++++++ specs/contact.md | 59 +++++++++++ specs/downloads.md | 39 ++++++++ specs/orders.md | 29 ++++++ specs/products.md | 40 ++++++++ specs/project-inquiry.md | 32 ++++++ specs/projects.md | 68 +++++++++++++ 11 files changed, 819 insertions(+) create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/DOMAIN_RULES.md create mode 100644 docs/FEATURES.md create mode 100644 docs/PROJECT_OVERVIEW.md create mode 100644 specs/admin.md create mode 100644 specs/contact.md create mode 100644 specs/downloads.md create mode 100644 specs/orders.md create mode 100644 specs/products.md create mode 100644 specs/project-inquiry.md create mode 100644 specs/projects.md diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..af4d6a7 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,211 @@ +# Architecture + +## Stack + +- Next.js (App Router) +- TypeScript +- next-intl +- Prisma + PostgreSQL +- Tailwind CSS +- Radix UI (via local primitives) +- framer-motion +- nodemailer + +--- + +# Application Structure + +## Public application + +Localized public pages live under: + +app/[locale]/(site) + +Locale routing and configuration are defined in: + +i18n/routing.ts + +The public layout checks the maintenance status and redirects visitors to: + +/coming-soon + +when maintenance mode is enabled. + +--- + +## Admin application + +Admin pages are implemented under: + +app/_admin + +Internal admin routing is rewritten to: + +app/admin-internal + +Development alias routes also exist under: + +app/root + +Routing decisions and host/path-based rewrites are implemented in: + +lib/admin-routing.ts + +The `_admin` structure should be treated as the canonical admin source. + +--- + +# Core Modules + +Application logic lives primarily in `lib/*`. + +Important modules include: + +lib/portfolio.ts +Handles portfolio queries and localized mapping. + +lib/app-config.ts +Provides application-level configuration values. + +lib/media.ts +Handles media library queries and media bindings. + +lib/mail.ts +Handles SMTP delivery via nodemailer. + +lib/contact-guard.ts +Handles Turnstile verification and rate limiting for contact submissions. + +These modules act as the primary server-side application layer. + +--- + +# UI Layer + +Shared UI primitives live in: + +components/ui + +These primitives wrap Radix UI components and define the shared design system. + +Public site UI components live in: + +components/site +components/layout + +Admin UI components live in: + +components/admin +components/dashboard + +Shared primitives must always originate from `components/ui`. + +Feature-level UI should reuse these primitives rather than reimplementing them. + +--- + +# Persistence Layer + +Database access is implemented using Prisma. + +Prisma client lives in: + +lib/prisma.ts + +Configuration values are stored in the database via: + +AppConfig + +which acts as a key-value store for runtime configuration values. + +Database access should always occur through server-side modules. + +Client components must never access Prisma directly. + +--- + +# Architectural Boundaries + +The following boundaries must be respected: + +- Client components must not access Prisma. +- Business logic must not live inside UI components. +- Shared UI must originate from `components/ui`. +- Public site UI belongs in `components/site`. +- Admin UI belongs in `components/admin` or `components/dashboard`. +- Server actions act as request entry points for form submissions. +- Server actions may call modules in `lib/*`. + +Database queries should not be implemented directly inside route-level UI files. + +--- + +# Request Flow Examples + +## Contact submission + +1. User submits the form on + +app/[locale]/(site)/contact/page.tsx + +2. Server action validates the input using Zod. +3. Turnstile verification and rate limiting run via: + +lib/contact-guard.ts + +4. Email is sent through: + +lib/mail.ts + +5. The user is redirected to: + +/success + +or back to the form with an error state. + +--- + +## Portfolio publishing + +1. Admin edits a project form. +2. Server action validates categories, fields, sections, and assets. +3. Media selections are resolved via: + +lib/media.ts + +4. Project data, sections, assets, and media usage are persisted via Prisma. +5. Public and admin paths are revalidated. + +--- + +# Canonical Sources + +The following files should be treated as canonical sources for specific domains: + +Routing +i18n/routing.ts + +Admin routing +lib/admin-routing.ts + +Prisma access +lib/prisma.ts + +Application configuration +lib/app-config.ts + +Portfolio logic +lib/portfolio.ts + +Media handling +lib/media.ts + +--- + +# Proposed Future Improvements (Not Implemented) + +These ideas are **not currently implemented** but may be introduced later: + +- Split `app-config` concerns into smaller modules if additional domains are added. +- Introduce dedicated models instead of expanding the `AppConfig` key-value store. +- Introduce explicit service boundaries if the application grows significantly.ڑ \ No newline at end of file diff --git a/docs/DOMAIN_RULES.md b/docs/DOMAIN_RULES.md new file mode 100644 index 0000000..1d11e65 --- /dev/null +++ b/docs/DOMAIN_RULES.md @@ -0,0 +1,92 @@ +# Domain Rules + +## Portfolio + +### Current implementation + +- A project must belong to one category +- Categories cannot be deleted while linked projects exist +- Public portfolio pages only show published projects +- Category filters only use active categories +- Project content is localized across + +`ar` + +, + +`en` + +, + +`de` + +- Project sections and assets are ordered by + +`sortOrder` + +- Project view mode is limited to: + - `GRID` + - `STORY` + - `CASE_STUDY` + +## Media + +### Current implementation + +- Media assets are tracked separately from portfolio records +- Media usage bindings connect assets to entity fields +- Usage binding is unique by + +`usageType + entityType + entityId + fieldKey` + +- Media is currently used by: + - portfolio cover + - portfolio sections + - portfolio assets + - site settings + +## Contact + +### Current implementation + +- Contact submission requires valid name, email, and message +- Turnstile is optional and controlled by settings +- Rate limiting is optional and keyed by hashed client IP plus time window +- Successful submission sends email only +- No submission record is stored in the database + +## Admin + +### Current implementation + +- Admin access depends on environment configuration +- Middleware can require HTTP Basic Auth before app access +- In-app admin session is cookie-based +- Repeated failed password attempts trigger temporary lockout + +## Configuration + +### Current implementation + +- Global settings are stored in + +`AppConfig` + +- Site settings, SMTP settings, contact protection, marquee settings, and maintenance mode all depend on configuration keys + +## Recommended Improvements + +- Add explicit domain rules for future + +`products` + +, + +`orders` + +, + +`downloads` + +only after data models exist +- Introduce database retention and moderation rules for contact or inquiry submissions if they become persisted diff --git a/docs/FEATURES.md b/docs/FEATURES.md new file mode 100644 index 0000000..634efef --- /dev/null +++ b/docs/FEATURES.md @@ -0,0 +1,63 @@ +# Features + +## Current Implementation + +### Public site + +- Localized homepage with service positioning and marquee content +- About page with profile-oriented content +- Portfolio list with category filtering +- Portfolio detail pages with multiple view modes: + - `GRID` + - `STORY` + - `CASE_STUDY` +- Contact form with: + - validation + - optional Turnstile + - rate limiting + - email delivery +- Success page after contact submission +- Maintenance redirect flow + +### Admin + +- Password-based app login plus optional Basic Auth gateway +- Dashboard summary cards +- Portfolio category management +- Portfolio project creation and editing +- Section and asset management inside each project +- Media library with usage bindings +- Site settings management +- SMTP settings and test email +- Contact protection settings +- Marquee settings +- Maintenance toggle +- UI Kit preview page + +## Present But Not Implemented As Full Features + +- `Products` + - only appears as a disabled navigation label +- `Downloads` + - document assets can be opened from portfolio detail pages, but there is no standalone downloads domain + +## Not Currently Implemented + +- `Orders` +- `Project Inquiry` as a separate workflow or model +- Customer accounts +- Checkout or payment handling + +## Recommended Improvements + +- Add explicit feature boundaries between + +`portfolio` + +content and future + +`products/orders/downloads` + +domains +- Store inbound contact submissions if business follow-up requires history +- Add tests for admin server actions and middleware routing diff --git a/docs/PROJECT_OVERVIEW.md b/docs/PROJECT_OVERVIEW.md new file mode 100644 index 0000000..c1b8595 --- /dev/null +++ b/docs/PROJECT_OVERVIEW.md @@ -0,0 +1,138 @@ +# Project Overview + +## Summary + +This project is a multilingual + +`Next.js` + +portfolio website with an authenticated + +`admin` + +workspace. + +The current implementation centers on: + +- Public marketing pages +- Portfolio listing and portfolio detail pages +- Contact form submission by email +- Global site configuration stored in + +`AppConfig` + +- Media library management +- Portfolio content management +- Maintenance mode + +## Current Implementation + +### Public site + +- Localized routes for + +`de` + +, + +`en` + +, + +`ar` + +- Main pages: + +`/` + +, + +`/about` + +, + +`/portfolio` + +, + +`/portfolio/category/[slug]` + +, + +`/portfolio/[slug]` + +, + +`/contact` + +, + +`/success` + +, + +`/coming-soon` + +- Header includes a disabled + +`/products` + +navigation item marked as + +`Soon` + +### Admin workspace + +- Login protected by Basic Auth at middleware level and password session inside the app +- Dedicated sections for: + - Overview + - Maintenance + - UI Kit + - Media Library + - Site Settings + - Marquee Settings + - SMTP Settings + - Contact Protection + - Portfolio management + +### Data model + +Current persistent entities in + +`prisma/schema.prisma` + +: + +- `AppConfig` +- `Category` +- `PortfolioProject` +- `PortfolioSection` +- `PortfolioAsset` +- `MediaAsset` +- `MediaUsage` + +No current models exist for: + +- `Product` +- `Order` +- `Download` +- `ProjectInquiry` + +## Recommended Improvements + +- Replace the placeholder + +`README.md` + +with project-specific onboarding +- Add explicit domain documentation for current + +`portfolio` + +versus planned future commerce features +- Add persistent storage for inbound contact and inquiry submissions if auditability is required +- Add role separation if the + +`admin` + +area will be used by more than one operator diff --git a/specs/admin.md b/specs/admin.md new file mode 100644 index 0000000..c32fb99 --- /dev/null +++ b/specs/admin.md @@ -0,0 +1,48 @@ +# Admin Feature Spec + +## Current Implementation + +### Access model + +- Middleware can protect admin routes with Basic Auth +- App login requires configured password and signed cookie session +- Failed password attempts trigger lockout + +### Routing + +- Source pages live in + +`app/_admin` + +- Middleware rewrites to + +`app/admin-internal` + +- Development compatibility routes exist under + +`app/root` + +### Capabilities + +- Overview dashboard +- Maintenance mode +- Media Library +- Site Settings +- Marquee Settings +- SMTP Settings +- Contact Protection +- Portfolio categories +- Portfolio projects +- UI Kit page + +## Constraints + +- Admin currently assumes a single shared operator credential model +- No role-based access control exists +- No audit log exists + +## Recommended Improvements + +- Add per-user authentication if multiple operators are expected +- Add action audit logging for content and configuration changes +- Add tests around middleware rewriting and auth edge cases diff --git a/specs/contact.md b/specs/contact.md new file mode 100644 index 0000000..7503aa1 --- /dev/null +++ b/specs/contact.md @@ -0,0 +1,59 @@ +# Contact Feature Spec + +## Current Implementation + +### Public flow + +- Public contact page exists at + +`/contact` + +- Form fields: + - name + - email + - phone + - company + - message +- Submission uses a server action +- Success redirects to + +`/success` + +### Protection + +- Validation uses + +`zod` + +- Optional Cloudflare Turnstile verification +- Optional rate limiting by IP window + +### Delivery + +- Messages are sent by SMTP through + +`nodemailer` + +- Recipient configuration comes from admin settings +- Messages are not persisted in the database + +### Admin controls + +- SMTP settings page +- Test email action +- Contact protection settings page + +## Risks + +- Contact history is lost if email delivery succeeds but later needs auditing +- Rate-limit counters are stored in + +`AppConfig` + +which mixes operational and business configuration + +## Recommended Improvements + +- Store contact submissions if the business needs pipeline visibility +- Add spam and abuse observability +- Add structured delivery error reporting diff --git a/specs/downloads.md b/specs/downloads.md new file mode 100644 index 0000000..c5fdc9c --- /dev/null +++ b/specs/downloads.md @@ -0,0 +1,39 @@ +# Downloads Feature Spec + +## Current Implementation + +- Portfolio assets support + +`DOCUMENT` + +files +- Portfolio detail pages expose document links with an + +`Open document` + +action +- Media library can store document assets + +## Gaps + +- No standalone downloads index exists +- No download access rules exist +- No download analytics or gating exists +- No dedicated + +`Download` + +model exists + +## Proposed Scope + +This is a proposed feature, not an implemented one. + +- Central downloads listing +- Optional download categories +- Optional gated download access +- Download tracking + +## Recommended First Step + +- Decide whether downloads remain a portfolio asset type or become their own domain diff --git a/specs/orders.md b/specs/orders.md new file mode 100644 index 0000000..17a41e3 --- /dev/null +++ b/specs/orders.md @@ -0,0 +1,29 @@ +# Orders Feature Spec + +## Current Implementation + +- No + +`Order` + +model exists +- No checkout flow exists +- No payment integration exists +- No admin order management exists + +## Proposed Scope + +This is a proposed feature, not an implemented one. + +- Order creation from products or inquiry conversions +- Order status lifecycle +- Admin order review and fulfillment tracking +- Email notifications for order events + +## Recommended First Step + +- Clarify whether + +`orders` + +means ecommerce checkout, service bookings, or manual sales records diff --git a/specs/products.md b/specs/products.md new file mode 100644 index 0000000..4eb37eb --- /dev/null +++ b/specs/products.md @@ -0,0 +1,40 @@ +# Products Feature Spec + +## Current Implementation + +- No + +`Product` + +model exists +- No public + +`/products` + +route exists +- No admin CRUD exists for products +- The site header contains a disabled + +`Products` + +navigation item marked as + +`Soon` + +## Proposed Scope + +This is a proposed feature, not an implemented one. + +- Public product listing page +- Product detail page +- Product media and downloadable assets +- Admin product CRUD +- Optional relation from products to portfolio case studies + +## Recommended First Step + +- Define a dedicated + +`Product` + +data model before any UI work diff --git a/specs/project-inquiry.md b/specs/project-inquiry.md new file mode 100644 index 0000000..f335131 --- /dev/null +++ b/specs/project-inquiry.md @@ -0,0 +1,32 @@ +# Project Inquiry Feature Spec + +## Current Implementation + +- No separate + +`ProjectInquiry` + +model exists +- No dedicated project inquiry route exists +- Current CTAs route users to the generic contact form + +## Proposed Scope + +This is a proposed feature, not an implemented one. + +- Inquiry form specifically for new project leads +- Optional prefilled source context from portfolio or homepage CTA +- Inquiry status tracking in admin +- Possible conversion into + +`Order` + +or CRM lead later + +## Recommended First Step + +- Decide whether project inquiry should stay a specialized + +`contact` + +variant or become a persisted lead-management feature diff --git a/specs/projects.md b/specs/projects.md new file mode 100644 index 0000000..4d22954 --- /dev/null +++ b/specs/projects.md @@ -0,0 +1,68 @@ +# Projects Feature Spec + +## Scope + +This spec documents the currently implemented + +`portfolio projects` + +domain. + +## Current Implementation + +### User-facing + +- Users can browse published projects on + +`/portfolio` + +- Users can filter by category +- Users can open a project detail page by slug +- Project detail can render rich sections, galleries, stats, deliverables, and links +- Document assets can be opened from project detail pages + +### Admin-facing + +- Admin can create, edit, publish, unpublish, and delete projects +- Admin can assign one category per project +- Admin can manage: + - localized titles and summaries + - client name + - project year + - service label + - preview URL + - cover image + - sections + - assets + - featured flag + - published flag + - sort order + - view mode + +### Data model + +- `PortfolioProject` +- `PortfolioSection` +- `PortfolioAsset` +- `Category` + +## Constraints + +- Only published projects appear publicly +- Category delete is blocked if projects exist +- Each project must have exactly one category +- View mode is limited to existing enum values + +## Recommended Improvements + +- Rename this feature from + +`portfolio` + +to + +`projects` + +only if the business wants portfolio and project management to be the same domain +- Add preview workflow instead of relying only on publish state +- Add revision history for content changes