Files
ai-gift-planner-mockup/gift-app-spec-v1.md
Norbert Maciaszek 0be01758e3 init spec
2025-12-26 22:19:47 +01:00

421 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gift Planning App MVP Specification
**Project Name:** Gift Planner
**Created:** December 26, 2025
**Status:** Pre-development / Discovery Phase
---
## 1. Project Vision & Goals
### Business Goal
Aplikacja wspomaga planowanie i śledzenie prezentów na dowolne okazje (święta, urodziny, rocznice), automatyzując zarządzanie budżetem, listami osób i śledzeniem cen.
### Success Metrics (do doprecyzowania)
- Liczba zarejestrowanych userów
- % userów, którzy ukończy workflow od okazji do budżetu
- Engagement z AI recommendations
- Średni czas planowania okazji
### Ograniczenia na start
- Budżet: TBD
- Deadline MVP: TBD
- Zespół: TBD
- Geograficznie: Polska (Ceneo integration)
---
## 2. Core Domain MVP Scope
### User & Authentication
- [ ] Rejestracja / logowanie (email + hasło)
- [ ] Profil usera (opcjonalnie: foto, preferencje powiadomień)
- [ ] **Bez social logins na MVP**
- [ ] Brak współdzielenia list (single-user na MVP)
### Globalna Lista Osób (User Resource)
Przypisana do usera, reużywalna między okazjami.
**Pola:**
- `id`, `userId`
- `name` (imię/pseudonim)
- `relation` (np. matka, przyjaciel, partner dla kontekstu AI)
- `age` (opcjonalnie, dla AI recommendations)
- `interests` (notatki/tagi: sport, gaming, moda itp.)
- `notes` (dowolne notatki)
- `createdAt`, `updatedAt`
**Operacje:**
- CRUD na osobach
- Lista osób dla danego usera
- Search/filter po nazwie
---
### Okazja (Occasion)
Kontener dla prezentów i budżetu w konkretnym kontekście czasowym.
**Pola:**
- `id`, `userId`
- `title` (np. "Święta 2025", "Urodziny Anny")
- `description` (opcjonalnie)
- `date` (przybliżona data okazji)
- `totalBudget` (opcjonalnie, całkowity budżet na okazję)
- `status` (draft, planning, shopping, done)
- `createdAt`, `updatedAt`
**Operacje:**
- CRUD na okazjach
- Lista okazji dla danego usera
- Filtry: aktywne, przeszłe, po dacie
---
### Powiązanie Osoba ↔ Okazja
Tablica łączy osoby z okazjami (wiele-do-wielu).
**Pola:**
- `id`, `occasionId`, `personId`
- `budgetPerPerson` (opcjonalnie, Budget przydzielony dla tej osoby na tę okazję)
- `notes` (opcjonalnie, specyficzne notatki dla tej osoby w ramach tej okazji)
- `createdAt`
**Operacje:**
- Dodaj osoby do okazji (można masowo)
- Usuń osobę z okazji
- Edytuj budżet per osoba
---
### Prezent (Gift)
Konkretny prezent przypisany do osoby w ramach okazji.
**Pola:**
- `id`, `occasionId`, `personId`
- `title` (nazwa prezentu)
- `status` (idea, selected, bought, wrapped, given lub podobne state machine)
- `price` (cena szacunkowa lub aktualna z Ceneo)
- `budget` (z czego się liczy: czy wlicza się w budżet osoby?)
- `description` (opcjonalnie, szczegóły)
- `url` (opcjonalnie, link do produktu/sklepu)
- `createdAt`, `updatedAt`
**Operacje:**
- CRUD na prezentach
- Change status prezentu
- Lista prezentów per osoba
- Lista prezentów per okazja (agregat)
---
### Budżet & Postęp (Occasion Analytics)
Obliczone **automatycznie** na podstawie prezentów i okazji.
**Per Okazja:**
- Całkowity budżet (suma `totalBudget` lub suma `budgetPerPerson` dla wszystkich osób)
- Wydane dotychczas (suma `price` prezentów ze statusem ≥ "selected")
- Pozostały budżet
- % wykorzystania budżetu
- Liczba osób
- Liczba prezentów (total, ready/wrapped, pending)
**UI Representation:**
- Progress bar: wydane / budżet
- Liczniki: "3 z 5 osób gotowych", "12 z 15 prezentów"
- Alert, jeśli przekraczamy budżet
---
## 3. Secondary Features Phase 2 (Post-MVP)
### Price Tracking via Ceneo
**Architecture:**
- User dodaje `url` do prezentu (dowolny link, np. ceneo.pl/...)
- Backend: cron job (raz dziennie lub częściej) + manualne "refresh" przez UI
- Pobieranie aktualnej ceny z API Ceneo / scrapingiem (Apify)
- Zapis snapshotu ceny do tabeli `PriceSnapshot(giftId, price, timestamp, source)`
**Pola Gift (extended):**
- `currentPrice` (najniższa cena z ostatniego snapshotu)
- `priceHistory` (relacja do `PriceSnapshot`)
- `priceAlert` (boolean: czy śledzić zmiany cen?)
- `priceAlertThreshold` (opcjonalnie: powiadom, gdy spadnie poniżej X)
**UI Features:**
- Mini-sparkline / mini-wykres ostatnich 30 dni cen
- Badge: "Najtaniej w 2 tygodniach" lub "Drożej o X%" od średniej
- Alert: "Cena spadła poniżej progu dobry moment!"
**Powiadomienia (Phase 2):**
- Email/push alert, gdy cena spadnie poniżej threshold
- Reminder: "Zbliżają się święta ceny mogą wzrosnąć"
- Scheduled reminder: "Sprawdzaj ceny tego prezentu co 3 dni"
---
### AI Gift Recommendations (Phase 2)
**Use Case:**
User przychodzi na okazję, widzi osobę w liście, kliknie "Suggest Gifts" → AI generuje 510 propozycji z uzasadnieniami.
**Input Context (AI):**
- Profil osoby: wiek, zainteresowania, relacja
- Okazja: typ, budżet per osoba, pozostały budżet na całą okazję
- Historia: jakie prezenty już kupił/planuje dla tej osoby w historii (unikaj duplikatów)
- Unikalność: weź pod uwagę, jakie prezenty planuje dla innych osób (różnorodność)
**Output:**
- Lista propozycji: [{ title, category, priceRange, reason, matchScore }]
- Reason: "Lubisz gaming, a wiek sugeruje..." itp.
- Link do szukania: łatwe przejście do Ceneo/Google Shopping
**Implementacja:**
- LLM (OpenAI API / local Ollama / inne)
- Prompt engineering: struktura context + constraints (budżet, unikalne przedmioty)
- User ręcznie decyduje, co dodać (zero auto-dodawania, pełna kontrola)
---
## 4. Architektura Techniczna (High Level)
### Tech Stack (Proposed)
- **Frontend:** React 19 + Next.js (App Router)
- Server Components dla list/agregacji
- Client Components dla interaktywnych formularzy
- TanStack Query do synchronizacji danych
- **Backend:** Node.js / Next.js API Routes lub oddzielny backend (Express/NestJS)
- REST API lub GraphQL (tbd)
- Autentykacja: JWT / session-based
- **Database:** PostgreSQL (+ Prisma ORM)
- Wersjonowanie: migrations
- **External Services:**
- Ceneo API / Apify scraper (Phase 2)
- OpenAI API lub self-hosted LLM (Phase 2)
- Email service (e.g., SendGrid, Resend) dla alertów (Phase 2)
- **Deployment:** TBD (Vercel, self-hosted, AWS, etc.)
---
### Database Schema (Sketch)
```
User
├── id (PK)
├── email (UNIQUE)
├── password_hash
├── created_at
└── updated_at
Person
├── id (PK)
├── user_id (FK)
├── name
├── relation
├── age
├── interests (TEXT / JSON)
├── notes
├── created_at
├── updated_at
Occasion
├── id (PK)
├── user_id (FK)
├── title
├── description
├── date
├── total_budget
├── status (draft | planning | shopping | done)
├── created_at
├── updated_at
OccasionPerson (M2M)
├── id (PK)
├── occasion_id (FK)
├── person_id (FK)
├── budget_per_person
├── notes
├── created_at
Gift
├── id (PK)
├── occasion_id (FK)
├── person_id (FK)
├── title
├── status (idea | selected | bought | wrapped | given)
├── price
├── description
├── url
├── price_alert (BOOLEAN)
├── price_alert_threshold (DECIMAL, optional)
├── created_at
├── updated_at
PriceSnapshot (Phase 2)
├── id (PK)
├── gift_id (FK)
├── price (DECIMAL)
├── source (e.g., "ceneo", "direct")
├── timestamp
├── created_at
AIRecommendation (Phase 2, optional logging)
├── id (PK)
├── occasion_id (FK)
├── person_id (FK)
├── prompt_context (JSON)
├── result (JSON - lista propozycji)
├── created_at
```
---
### API Endpoints (MVP, Sketch)
#### Auth
- `POST /api/auth/register` → register user
- `POST /api/auth/login` → login user
- `POST /api/auth/logout` → logout
#### Persons
- `GET /api/persons` → list all persons for logged user
- `POST /api/persons` → create person
- `PUT /api/persons/:id` → update person
- `DELETE /api/persons/:id` → delete person
#### Occasions
- `GET /api/occasions` → list occasions for logged user
- `POST /api/occasions` → create occasion
- `PUT /api/occasions/:id` → update occasion
- `DELETE /api/occasions/:id` → delete occasion
- `GET /api/occasions/:id` → get occasion with full context
#### OccasionPerson (Managing persons in occasion)
- `POST /api/occasions/:id/persons` → add person(s) to occasion
- `DELETE /api/occasions/:id/persons/:personId` → remove person
- `PUT /api/occasions/:id/persons/:personId` → update budget_per_person
#### Gifts
- `GET /api/occasions/:id/gifts` → list gifts for occasion
- `POST /api/occasions/:id/gifts` → create gift for person
- `PUT /api/gifts/:id` → update gift (title, status, price, url, etc.)
- `DELETE /api/gifts/:id` → delete gift
#### Occasion Analytics (computed read-only)
- `GET /api/occasions/:id/analytics` → budget, postęp, countdowny
---
## 5. UI/UX Flow (MVP)
### Key Views
#### 1. Dashboard (Home)
- Welcome message
- List okazji (karty): aktywne vs archiwalne
- Quick stats: ile osób/prezentów do kupienia, budżet całkowity
- Shortcuts: "+ New Occasion", "+ Quick Add Gift"
#### 2. Okazja Detail (Single Occasion)
- Nagłówek: nazwa, data, budżet, progress bar
- 2 widoki (tabbed):
- **Persons Tab:** lista osób z budżetami, możliwość dodania, usunięcia, edycji budżetu
- **Gifts Tab (list view):** wszystkie prezenty dla okazji, szybka edycja statusu/ceny, agregat budżetu
#### 3. Osoba Detail (+ Gifts for this Person)
- Info: imię, wiek, zainteresowania, notatki
- Lista prezentów dla tej osoby (w kontekście aktualnej okazji)
- Button: "AI Suggestions" (Phase 2)
- Edycja danych osoby
#### 4. Gift Detail
- Edycja: nazwa, status, cena, URL, opis
- Link preview (opcjonalnie: og:image)
- Price tracker (Phase 2): mini-chart, alerts
- Delete/Archive
#### 5. Settings (Simple MVP)
- Profil usera
- Zmiana hasła
- Preferencje powiadomień (Phase 2)
- Logout
---
## 6. MVP Definition & Phasing
### MVP = Everything in Section 2 (Core Domain)
- ✅ User auth
- ✅ Persons management (global reusable list)
- ✅ Occasions CRUD
- ✅ Connect persons to occasions
- ✅ Gifts CRUD + status tracking
- ✅ Budget & postęp calculations
- ✅ Aggregate gift list per occasion
**Timeline:** ~48 weeks (team-dependent)
### Phase 2 (Post-MVP, ~4 weeks after)
- Price tracking via Ceneo + PriceSnapshot table
- Price alerts & notifications (email/push)
- AI gift recommendations (LLM integration)
### Phase 3+ (Nice-to-have, Later)
- Collaborative lists (share occasion with family)
- Analytics: roczne porównania, trendy wydatków
- Export to PDF/calendar
- Mobile app (native or responsive PWA)
- Social: wishlist sharing, gift registry
---
## 7. Key Decisions & Assumptions (To Validate)
- [ ] Single-user MVP (no collaboration) OK?
- [ ] Auth method: email/password or OAuth? (assuming email/pwd for MVP)
- [ ] Database: PostgreSQL assumption confirm?
- [ ] Ceneo integration: API lub web scraping? (Apify fallback)
- [ ] AI model: OpenAI API czy local/self-hosted? (cost/privacy trade-off)
- [ ] Monetization: subscription, freemium, ads? (affects feature gating)
- [ ] Mobile-first design czy desktop-first? (assuming mobile-responsive on MVP)
---
## 8. Next Steps
1. **Validate domain model** robi sens struktura User → Occasion → Person → Gift?
2. **Detailed API spec** co dokładnie zwraca endpoint?
3. **UI wireframes** sketche ekranów
4. **Phase 1 backlog** rozbić MVP na user stories + tasking
5. **Tech setup** inicjalizacja repo, struktura projektu, Prisma schema
6. **First feature cycle** login/register → Person CRUD → Occasion CRUD
---
## 9. Assumptions & Open Questions
### Business
- Czy aplikacja ma być darmowa czy z opcjami premium?
- Target audience: Polska czy szerzej?
- Launch timeline?
### Technical
- Czy self-hosted czy cloud (Vercel, Railway)?
- Rate limits dla Ceneo API czy backup plan?
- Jak long-term archivizować stare okazje?
### Product
- Czy dark mode na MVP?
- Czy offline support (PWA)?
- Czy mobile app native czy Web + PWA?
---
**Document Version:** 1.0
**Last Updated:** December 26, 2025
**Status:** Awaiting validation & feedback