486 lines
6.5 KiB
Markdown
486 lines
6.5 KiB
Markdown
💍 AGENTS.md
|
||
|
||
Wedding App – Agent Specification (Hero + Secure + Group Edition)
|
||
|
||
1. Project Overview
|
||
|
||
A private wedding web application for invited guests.
|
||
|
||
Production URL:
|
||
|
||
https://www.svenja-dominic-hochzeit.de/
|
||
|
||
The entire platform is protected by login.
|
||
There is no public content accessible without authentication.
|
||
|
||
Core Goals
|
||
|
||
invitation-based access system
|
||
|
||
group-based RSVP handling
|
||
|
||
photo upload + shared gallery with permission control
|
||
|
||
modern information pages (schedule, hotels, taxi, location)
|
||
|
||
embedded Google Maps (2-click solution)
|
||
|
||
external link to official location website
|
||
|
||
language switch (German / English)
|
||
|
||
visually polished, modern, mobile-first UI
|
||
|
||
2. Access Model (IMPORTANT – UPDATED)
|
||
|
||
The entire site must be login-protected.
|
||
|
||
No publicly accessible landing page.
|
||
|
||
Invitation-Based Authentication Model
|
||
|
||
Each account represents one invitation.
|
||
|
||
An invitation can be:
|
||
|
||
a single person
|
||
|
||
a family
|
||
|
||
a couple
|
||
|
||
any defined group
|
||
|
||
Even single guests are technically treated as a group with one member.
|
||
|
||
Login Flow
|
||
|
||
User visits root URL → redirected to login
|
||
|
||
User enters:
|
||
|
||
group password
|
||
|
||
group name (predefined)
|
||
|
||
On success:
|
||
|
||
group loaded from database
|
||
|
||
session created
|
||
|
||
redirect to internal start page
|
||
|
||
No free registration allowed.
|
||
|
||
Each group has:
|
||
|
||
a predefined group name
|
||
|
||
an individual password
|
||
|
||
Different groups → different passwords.
|
||
|
||
Group Management After Login
|
||
|
||
After login, the group sees:
|
||
|
||
all predefined members of their invitation
|
||
|
||
RSVP selection per member
|
||
|
||
For each member:
|
||
|
||
attending Yes / No
|
||
|
||
Only one person per group must log in and manage the responses.
|
||
|
||
3. Roles System (NEW)
|
||
|
||
Two roles must exist:
|
||
|
||
Role: Guest (Default)
|
||
|
||
Can:
|
||
|
||
manage RSVP for their group
|
||
|
||
upload images
|
||
|
||
delete only their own uploaded images
|
||
|
||
Cannot:
|
||
|
||
delete images uploaded by others
|
||
|
||
Role: Admin (Hosts)
|
||
|
||
Can:
|
||
|
||
delete any uploaded image
|
||
|
||
manage all groups
|
||
|
||
optionally view attendance overview
|
||
|
||
No public admin panel required, but role logic must exist internally.
|
||
|
||
4. Internal Start Page Structure (Hero + Dashboard Concept)
|
||
|
||
After login, the start page consists of two sections:
|
||
|
||
Section 1 – Hero Area (Emotional Welcome)
|
||
|
||
Must include:
|
||
|
||
large background image
|
||
|
||
headline:
|
||
“Willkommen zu unserer Hochzeit”
|
||
|
||
wedding date
|
||
|
||
short personal text
|
||
|
||
smooth scroll transition to dashboard
|
||
|
||
Purpose:
|
||
|
||
Make the platform feel emotional and elegant, not like a business app.
|
||
|
||
Section 2 – Dashboard Area
|
||
|
||
Below the hero section:
|
||
|
||
Card-based grid layout containing:
|
||
|
||
RSVP
|
||
|
||
Upload
|
||
|
||
Gallery
|
||
|
||
Ablauf (Schedule)
|
||
|
||
Hotels
|
||
|
||
Taxi
|
||
|
||
Location
|
||
|
||
Dashboard must:
|
||
|
||
use rounded cards
|
||
|
||
soft shadows
|
||
|
||
consistent spacing
|
||
|
||
mobile-first responsive layout
|
||
|
||
Navigation Requirement (NEW)
|
||
|
||
A back button (arrow icon) must exist:
|
||
|
||
visible in header area
|
||
|
||
allows navigation back to previous page
|
||
|
||
must NOT replace logout button
|
||
|
||
Logout remains separate and visible.
|
||
|
||
5. Tech Stack (Required)
|
||
|
||
Python 3.12
|
||
Flask
|
||
Gunicorn
|
||
uv (dependency management)
|
||
SQLite
|
||
Docker + Docker Compose
|
||
|
||
Frontend:
|
||
|
||
Jinja2 templates
|
||
Tailwind via CDN OR lightweight custom CSS
|
||
No heavy JS frameworks
|
||
Minimal JavaScript only where needed
|
||
|
||
6. UI / UX Requirements (Very Important)
|
||
|
||
Visual style:
|
||
|
||
elegant and modern
|
||
|
||
wedding-like aesthetic
|
||
|
||
soft spacing
|
||
|
||
rounded elements
|
||
|
||
subtle shadows
|
||
|
||
warm color palette (cream / beige / dark green / gold accents)
|
||
|
||
clean typography (Google Fonts allowed)
|
||
|
||
Mobile-first design required.
|
||
|
||
Minimal clutter.
|
||
Smooth hover transitions.
|
||
|
||
7. Language Switch (DE / EN)
|
||
|
||
Must include:
|
||
|
||
language toggle in header
|
||
|
||
switch stored in session
|
||
|
||
no automatic geo-detection
|
||
|
||
static text controlled via simple translation dictionary
|
||
|
||
8. RSVP Logic (UPDATED – GROUP BASED)
|
||
|
||
Database structure must support:
|
||
|
||
group entity
|
||
|
||
group members
|
||
|
||
Each group contains:
|
||
|
||
multiple persons
|
||
|
||
For each person:
|
||
|
||
attending (boolean)
|
||
|
||
Optional plus-one logic may be removed since groups now define structure.
|
||
|
||
Persist responses per individual.
|
||
|
||
9. Image Upload & Gallery System (UPDATED)
|
||
Upload Requirements
|
||
|
||
Allowed types:
|
||
|
||
jpg
|
||
|
||
jpeg
|
||
|
||
png
|
||
|
||
Must:
|
||
|
||
validate file extension
|
||
|
||
validate MIME type
|
||
|
||
limit file size (configurable)
|
||
|
||
sanitize filenames
|
||
|
||
prevent path traversal
|
||
|
||
store files in /uploads
|
||
|
||
store reference in database
|
||
|
||
Uploads must support:
|
||
|
||
mobile gallery uploads (iOS / Android compatible input field)
|
||
|
||
Optional but recommended:
|
||
|
||
remove EXIF metadata before saving
|
||
|
||
Gallery Requirements
|
||
|
||
All authenticated guests see all images.
|
||
|
||
Responsive grid layout.
|
||
|
||
Click → larger modal view.
|
||
|
||
Image Permissions (NEW)
|
||
|
||
Guest:
|
||
|
||
may delete only images where:
|
||
image.uploaded_by == current_user.id
|
||
|
||
Admin:
|
||
|
||
may delete any image
|
||
|
||
Every image must have:
|
||
|
||
visible download button
|
||
|
||
direct file download (no right-click dependency)
|
||
|
||
Optional:
|
||
|
||
future ZIP export of all images
|
||
|
||
10. Location Page Requirements
|
||
|
||
Must include:
|
||
|
||
Location name (env variable)
|
||
|
||
Address (env variable)
|
||
|
||
Google Maps embed (iframe)
|
||
|
||
Prominent button:
|
||
|
||
“Zur Location-Webseite” / “Visit Location Website”
|
||
|
||
target="_blank"
|
||
rel="noopener"
|
||
|
||
Environment variables:
|
||
|
||
LOCATION_NAME
|
||
LOCATION_ADDRESS
|
||
LOCATION_WEBSITE_URL
|
||
GOOGLE_MAPS_EMBED_URL
|
||
|
||
Google Maps Privacy Requirement
|
||
|
||
Google Maps must NOT load automatically.
|
||
|
||
Implement 2-click solution:
|
||
|
||
Show placeholder container
|
||
|
||
Display privacy notice
|
||
“Zur Anzeige der Karte werden Daten an Google übertragen.”
|
||
|
||
Only after user click → load iframe dynamically
|
||
|
||
No global cookie banner required.
|
||
|
||
11. Database Schema (UPDATED)
|
||
|
||
Table: groups
|
||
|
||
id (PK)
|
||
|
||
name (required)
|
||
|
||
password_hash
|
||
|
||
role (guest / admin)
|
||
|
||
created_at
|
||
|
||
Table: group_members
|
||
|
||
id (PK)
|
||
|
||
group_id (FK)
|
||
|
||
name
|
||
|
||
attending (boolean, nullable)
|
||
|
||
Table: uploads
|
||
|
||
id (PK)
|
||
|
||
filename
|
||
|
||
uploaded_by (group id)
|
||
|
||
uploaded_at (timestamp)
|
||
|
||
SQLite only.
|
||
|
||
12. Legal Pages (Important)
|
||
|
||
Must implement:
|
||
|
||
/datenschutz
|
||
/impressum
|
||
|
||
Both:
|
||
|
||
accessible without login (legal requirement)
|
||
|
||
linked in footer
|
||
|
||
always visible
|
||
|
||
13. Dependency Management Rules
|
||
|
||
Use uv.
|
||
|
||
Dependencies defined in:
|
||
|
||
pyproject.toml
|
||
|
||
Commit:
|
||
|
||
uv.lock
|
||
|
||
No requirements.txt allowed.
|
||
|
||
Docker must run:
|
||
|
||
uv sync --frozen --no-dev
|
||
|
||
14. Docker Requirements
|
||
|
||
Base image:
|
||
|
||
python:3.12-slim
|
||
|
||
Must:
|
||
|
||
install uv
|
||
|
||
copy pyproject.toml + uv.lock first (cache optimization)
|
||
|
||
run uv sync --frozen --no-dev
|
||
|
||
expose port 8000
|
||
|
||
Start with:
|
||
|
||
uv run gunicorn -b 0.0.0.0:8000 app:app
|
||
|
||
Uploads + SQLite database must use persistent volumes.
|
||
|
||
15. Non-Goals (Strict)
|
||
|
||
Do NOT implement:
|
||
|
||
email systemsnur
|
||
|
||
payment systems
|
||
|
||
OAuth
|
||
|
||
cloud storage
|
||
|
||
microservices
|
||
|
||
tracking tools
|
||
|
||
analytics tools
|
||
|
||
16. Design Philosophy
|
||
|
||
Aesthetic first, but not overengineered.
|
||
Simple, maintainable code.
|
||
Minimal dependencies.
|
||
Excellent mobile UX.
|
||
Elegant, mature, emotionally warm.
|
||
|
||
Not playful.
|
||
Not corporate.
|
||
Not overcomplex. |