483 lines
16 KiB
Markdown
483 lines
16 KiB
Markdown
# 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 (Market integration)
|
||
|
||
---
|
||
|
||
## 2. Core Domain – MVP Scope
|
||
|
||
### User, Authentication & Tokens
|
||
- [ ] Rejestracja / logowanie (email + hasło)
|
||
- [ ] Profil usera (opcjonalnie: foto, preferencje powiadomień)
|
||
- [ ] **Tokeny**: Miesięczny odnawialny limit tokenów + możliwość dokupienia pakietów.
|
||
- [ ] **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` (profilowanie AI: styl życia, ulubione kolory, unikanie konkretnych rzeczy)
|
||
- `createdAt`, `updatedAt`
|
||
|
||
**Pola (Rozszerzone UI):**
|
||
- `birthDate` (Data urodzin)
|
||
- `nameDay` (Data imienin - format MM-DD)
|
||
- `clothingSizes` (JSON: { top: "M", bottom: "38", shoe: "39" })
|
||
- `avoidances` (Alergie, rzeczy nielubiane - kluczowe dla AI)
|
||
- `links` (Wishlista, profil social media)
|
||
|
||
**Uwaga:** Specyficzne daty (jak urodziny osoby) są traktowane jako standardowe obiekty `Occasion`, co pozwala na przypisanie wielu prezentów do jednego wydarzenia osobistego.
|
||
|
||
**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
|
||
|
||
---
|
||
|
||
### Produkt (Product Master)
|
||
Baza rzeczywistych przedmiotów, które mogą być prezentami.
|
||
|
||
**Pola:**
|
||
- `id`
|
||
- `title` (nazwa modelu/produktu)
|
||
- `description` (pełny opis techniczny)
|
||
- `ean` / `sku`
|
||
- `imageUrl`
|
||
- `tags` (kategorie: kuchnia, gaming, itp.)
|
||
- `productUrl` (link do produktu / porównywarki)
|
||
- `globalMinPrice`, `globalMaxPrice` (z historii śledzenia)
|
||
|
||
---
|
||
|
||
### Prezent - Instancja (Gift / Planning Instance)
|
||
Konkretny plan podarowania produktu danej osobie na wybraną okazję.
|
||
|
||
**Pola:**
|
||
- `id`, `productId` (FK), `occasionId` (FK), `personId` (FK)
|
||
- `status` (idea, selected, bought, wrapped, given)
|
||
- `purchasePrice` (cena, za którą faktycznie kupiliśmy)
|
||
- `purchaseStore` (sklep, w którym dokonano zakupu)
|
||
- `orderNumber` (opcjonalnie)
|
||
- `personalNotes` (notatki specyficzne dla tego obdarowanego)
|
||
- `rating` (0-5 stars - ocena trafności prezentu)
|
||
- `feedbackNote` (notka po wręczeniu, np. "kolor za jasny")
|
||
- `createdAt`, `updatedAt`
|
||
|
||
**Operacje:**
|
||
- CRUD na instancjach prezentów
|
||
- Śledzenie statusu zakupu per osoba
|
||
- Powiązanie z globalną kartą produktu
|
||
|
||
---
|
||
|
||
### Centrum Aktualizacji (Updates Center)
|
||
Spersonalizowany feed powiadomień.
|
||
|
||
**Typy aktualizacji:**
|
||
- **Okazja cenowa**: Spadek ceny rynkowej produktu z karty produktu.
|
||
- **Zbliżająca się okazja**: Countdown do wydarzeń (globalnych i mini-okazji).
|
||
- **Inspiracja AI**: Nowe propozycje na podstawie profilu osoby.
|
||
- **Radar Prezentowy (Gift Radar)**: Monitoring cen, trendów i dostępności w czasie rzeczywistym z match-makingiem AI.
|
||
- **Raport budżetowy**: Podsumowanie wydatków w danym miesiącu.
|
||
|
||
---
|
||
|
||
### 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 & Market Analysis
|
||
|
||
**Architecture:**
|
||
- User dodaje `url` do prezentu (dowolny link)
|
||
- Backend: cron job (raz dziennie lub częściej) + manualne "refresh" przez UI
|
||
- Pobieranie aktualnej ceny z API sklepów / 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 & Greetings (Phase 2)
|
||
|
||
**Use Case 1: Recommendations**
|
||
User przychodzi na okazję, widzi osobę w liście, kliknie "Suggest Gifts" → AI generuje 5–10 propozycji z uzasadnieniami.
|
||
|
||
**Use Case 2: Greetings & Cards (New)**
|
||
AI generuje personalizowane życzenia na podstawie szerokiego kontekstu:
|
||
- **Widok Okazji (Grupowe)**: Generowanie życzeń dla wszystkich uczestników naraz (spójność stylistyczna, unikanie powtórzeń).
|
||
- **Widok Okazji (Indywidualne)**: Szybkie generowanie życzeń dla konkretnej osoby bezpośrednio z listy uczestników okazji (uwzględnia wybrany prezent).
|
||
|
||
**Input Context (AI):**
|
||
- Profil osoby: wiek, zainteresowania, relacja, styl życia, rozmiary.
|
||
- 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).
|
||
- Wybrane prezenty: konkretne modele produktów, ich cechy i przeznaczenie.
|
||
|
||
**Output:**
|
||
- Lista propozycji: [{ title, category, priceRange, reason, matchScore }]
|
||
- Życzenia: [{ recipient, occasion, text, tone, cardTypeSuggestion }]
|
||
|
||
**Implementacja:**
|
||
- LLM (OpenAI API / local Ollama / inne)
|
||
- Prompt engineering: struktura context + constraints (budżet, unikalne przedmioty).
|
||
- **Koszt AI**: Każda generacja sugestii lub pakietu życzeń kosztuje określoną liczbę tokenów (np. 1 token per życzenia / 5 sugestii).
|
||
- User ręcznie decyduje, co dodać lub skopiować.
|
||
|
||
---
|
||
|
||
## 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:**
|
||
- Market APIs / 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
|
||
├── tokens_balance (INT, default 0)
|
||
├── last_token_reset (TIMESTAMP)
|
||
├── 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
|
||
|
||
Product
|
||
├── id (PK)
|
||
├── title
|
||
├── description
|
||
├── imageUrl
|
||
├── tags (JSON)
|
||
├── ean
|
||
├── product_url
|
||
├── created_at
|
||
|
||
Gift (Planning Instance)
|
||
├── id (PK)
|
||
├── product_id (FK)
|
||
├── occasion_id (FK)
|
||
├── person_id (FK)
|
||
├── status (idea | selected | bought | wrapped | given)
|
||
├── purchase_price (cena zakupu)
|
||
├── purchase_store
|
||
├── personal_notes
|
||
├── rating (INT, 1-5)
|
||
├── feedback_note (TEXT)
|
||
├── created_at
|
||
|
||
IndividualOccasion (Zrezygnowano - używamy tabeli Occasion)
|
||
```
|
||
```
|
||
|
||
---
|
||
|
||
### 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)
|
||
- Recent Gifts: szybki podgląd ostatnio dodanych planów
|
||
- Active Occasions cards
|
||
- Quick AI Suggestions banner
|
||
|
||
#### 6. Kalendarz Okazji, Inspiracje i Poradniki (Templates & Blog)
|
||
* **Global Holidays**: Biblioteka ogólnych świąt (Dzień Matki, Boże Narodzenie) z opcją „Użyj jako szablon”.
|
||
* **Inspiracje (Global Products)**: Baza produktów sugerowanych przez AI, posortowana kategoriami (Elektronika, Wellness itp.).
|
||
* **Blog i Poradniki**: Serce treści SEO aplikacji. Artykuły łączące poradnictwo (np. "Jak wybrać prezent") z bezpośrednimi linkami do produktów i okazji.
|
||
- **Shoppable Content**: Możliwość dodawania produktów bezpośrednio z treści artykułu do planów użytkownika.
|
||
- **Nienachalne Reklamy**: Sekcje promujące konkretne marki lub produkty w kontekście merytorycznych wpisów.
|
||
- **Analiza Wektorowa AI**: Sugerowanie artykułów i produktów na podstawie zainteresowań wyłapanych z profili osób.
|
||
* **One-Click Add**: Możliwość szybkiego przypisania produktu z bazy inspiracji do konkretnej osoby i okazji w aplikacji.
|
||
* **Wyszukiwarka AI**: Interaktywne pole tekstowe pozwalające na dopytanie AI o konkretne pomysły spoza bazy.
|
||
|
||
#### 3. Centrum Aktualizacji (Updates)
|
||
- Feed powiadomień: price drops, countdowns, AI ideas, budget alerts
|
||
|
||
#### 3. Osoba Detail (Relationship Hub)
|
||
- Aktywne okazje osobiste i globalne (np. "Urodziny", "Święta")
|
||
- AI Profiler: zarządzanie preferencjami dla LLM
|
||
- Historia zakupowa ("Ostatnio kupione")
|
||
|
||
#### 4. Karta Produktu (Product Master)
|
||
- Globalna historia ceny (wykres 30 dni)
|
||
- Porównywarka cenowa (oferty sklepów)
|
||
- Lista planów, w których występuje ten produkt (re-use)
|
||
|
||
#### 5. Gift Planning (Instance View)
|
||
- Logistyka: status, notatki zakupowe, numer zamówienia
|
||
- Analiza ceny zakupu vs cena rynkowa
|
||
- **Feedback Loop**: Po zmianie statusu na "Otrzymany" (given), pojawia się sekcja oceny (gwiazdki + notatka efektu).
|
||
- *(Przeniesiono: Sekcja AI Greetings została przeniesiona do widoków Okazji i Osoby dla lepszego kontekstu).*
|
||
|
||
#### 6. Settings
|
||
- Profil usera i wylogowanie
|
||
|
||
#### 7. Globalny Budżet (Budget Hub)
|
||
- Wykres wydatków miesięcznych
|
||
- Podział na kategorie (Elektronika, Zabawki, Dom)
|
||
- Lista ostatnich transakcji
|
||
- Statystyki "Wydane w tym roku"
|
||
|
||
#### 8. Occasion Details (Tabs)
|
||
Widok okazji podzielony na zakładki:
|
||
1. **Lista Osób**: Karty osób z przypisanymi prezentami i budżetem per osoba.
|
||
2. **Wszystkie Prezenty**: Zbiorcza lista prezentów (Flat list) do łatwego zarządzania statusami (Kupione/Zapakowane).
|
||
3. **AI**: Sugestie, porady dotyczące optymalizacji oraz grupowe generowanie życzeń dla wszystkich uczestników.
|
||
|
||
---
|
||
|
||
## 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:** ~4–8 weeks (team-dependent)
|
||
|
||
- Price tracking + PriceSnapshot table
|
||
- Price alerts & notifications (email/push)
|
||
- AI gift recommendations (LLM integration)
|
||
- **Wyszukiwarka AI (AI Search)**: Globalna wyszukiwarka prezentów oparta na LLM z analizą dopasowania (match-making).
|
||
|
||
### 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?
|
||
- [ ] Market integration: API lub web scraping? (Apify fallback)
|
||
- [ ] AI model: OpenAI API czy local/self-hosted? (cost/privacy trade-off)
|
||
- [ ] Monetization:
|
||
- **Tokens**: Monthly allowance + top-ups for AI actions.
|
||
- **Pakiet "Oszczędzanie"**: 14.99 PLN / msc. Odblokowuje historię cen (od momentu dodania produktu, do 30 dni wstecz) i alerty cenowe.
|
||
- **Pakiet "Kontrola budżetu"**: 6.99 PLN / msc. Odblokowuje zaawansowane analizy budżetowe, wykresy wydatków i prognozy.
|
||
- [ ] 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 API sklepów 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
|