docs: add project documentation and initial specs

This commit is contained in:
MOH
2026-03-14 13:29:32 +01:00
parent 35734bd2d9
commit 143b441d0c
11 changed files with 819 additions and 0 deletions
+211
View File
@@ -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.ڑ
+92
View File
@@ -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
+63
View File
@@ -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
+138
View File
@@ -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
+48
View File
@@ -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
+59
View File
@@ -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
+39
View File
@@ -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
+29
View File
@@ -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
+40
View File
@@ -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
+32
View File
@@ -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
+68
View File
@@ -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