122 lines
6.9 KiB
Markdown
122 lines
6.9 KiB
Markdown
# GEMINI Project Context: SmurfHabits
|
||
|
||
This document provides a comprehensive overview of the SmurfHabits project for AI-assisted development.
|
||
|
||
## 1. Project Overview
|
||
|
||
SmurfHabits is a mobile-first web application for habit tracking with a light gamification layer. The core user loop involves completing daily habits and quests to earn rewards, which are then used to build and develop a virtual village. This progression grants Experience Points (EXP) that are tracked on a global leaderboard.
|
||
|
||
The project is a full-stack SPA (Single Page Application) built with Nuxt 3, using Vue 3 for the frontend and a Node.js backend powered by Nuxt Nitro. It uses SQLite as its database with Prisma ORM for data access.
|
||
|
||
### Key Architectural Principles:
|
||
- **Monorepo:** Frontend and backend coexist in a single codebase.
|
||
- **Backend as Source of Truth:** All progression, time-based calculations, and rewards are handled by the server-side API to ensure consistency.
|
||
- **Clear Separation of Concerns:** A strict distinction is maintained between UI (in `app/`), backend logic (in `server/`), and data persistence (in `prisma/`).
|
||
|
||
## 2. Building and Running
|
||
|
||
The project uses `npm` for dependency management and running scripts.
|
||
|
||
### First-Time Setup
|
||
1. **Install Node.js:** Ensure you are using a Node.js version in the 20.x LTS range.
|
||
2. **Install Dependencies:**
|
||
```bash
|
||
npm install
|
||
```
|
||
3. **Setup Database:** Create the initial database and apply migrations. The `.env` file is pre-configured to use a local SQLite file (`dev.db`).
|
||
```bash
|
||
npx prisma migrate dev
|
||
```
|
||
|
||
### Development
|
||
To run the development server with hot-reloading:
|
||
```bash
|
||
npm run dev
|
||
```
|
||
Никогда НЕ запускай npm run dev сам. Скажи пользователю, что бы сделал это сам.
|
||
|
||
### Building for Production
|
||
To build the application for production:
|
||
```bash
|
||
npm run build
|
||
```
|
||
Не запускай npm run build сам. Скажи пользователю, что бы сделал это сам.
|
||
|
||
## 3. Development Conventions
|
||
|
||
Adhering to these conventions is critical for maintaining project stability.
|
||
|
||
### Project Structure
|
||
- `app/`: Contains all frontend UI code (pages, components, layouts).
|
||
- `server/`: Contains all backend API code and utilities.
|
||
- `prisma/`: Contains the database schema (`schema.prisma`) and migration files.
|
||
- `public/`: Contains static assets.
|
||
|
||
### Database and Prisma
|
||
- The project is intentionally locked to **Prisma v6.x**. Do **NOT** upgrade to v7 or introduce Prisma adapters.
|
||
- All changes to the database schema in `prisma/schema.prisma` **must** be followed by a migration command:
|
||
```bash
|
||
npx prisma migrate dev
|
||
```
|
||
- The primary Prisma client instance is exported from `server/utils/prisma.ts`. Do not initialize the client elsewhere.
|
||
|
||
### State Management
|
||
- **Frontend:** Pinia is used for client-side state management.
|
||
- **Backend:** The backend API is the authoritative source for all user progression, rewards, and time-sensitive data. The frontend should not implement its own logic for these calculations.
|
||
|
||
### API Development
|
||
- API routes are located in `server/api/`.
|
||
- Group API endpoints by domain (e.g., `/api/habits`, `/api/village`).
|
||
- All business logic should reside in the backend.
|
||
|
||
### Data Conventions
|
||
- **`daysOfWeek` Field:** This array represents the days a habit is active. The week starts on **Monday**.
|
||
- Monday: `0`
|
||
- Tuesday: `1`
|
||
- Wednesday: `2`
|
||
- Thursday: `3`
|
||
- Friday: `4`
|
||
- Saturday: `5`
|
||
- Sunday: `6`
|
||
- **Daily Streak:** The `dailyStreak` field on the `User` model is an integer representing the user's consecutive daily visits. Its primary function is to act as a **multiplier for rewards** (coins and EXP) earned from completing habits and village activities.
|
||
- The multiplier is typically capped (e.g., at 3x).
|
||
- It is updated by the `calculateDailyStreak` function located in `server/utils/streak.ts`. This function determines if a visit extends the streak, maintains it, or resets it.
|
||
|
||
## 4. Date and Time Handling (Game Day Concept)
|
||
|
||
To ensure consistent and timezone-agnostic handling of daily game mechanics, the project employs a "Game Day" concept. This approach prioritizes the user's local calendar day for relevant actions and uses a standardized string format for persistence.
|
||
|
||
### Key Principles:
|
||
|
||
1. **"Game Day" Format:** All dates representing a calendar day (e.g., when a habit was completed, a daily visit occurred, or a village event was processed) are stored and primarily handled as a **`String` in "YYYY-MM-DD" format**. This includes fields like `DailyVisit.date`, `HabitCompletion.date`, `VillageObject.lastExpDay`, `VillageTile.clearingStartedDay`, and `Village.lastTickDay`.
|
||
|
||
2. **Client as Source of Truth for User's Day:**
|
||
* For user-initiated actions (e.g., completing a habit, triggering a daily visit), the **frontend (client-side)** determines the current "Game Day" based on the user's local timezone.
|
||
* This "YYYY-MM-DD" string is then sent to the backend with the API request. This prevents timezone conflicts where the server's day might differ from the user's local perception of "today."
|
||
|
||
3. **Server-Side Consistency with UTC:**
|
||
* On the backend, when parsing these "YYYY-MM-DD" strings into `Date` objects for calculations (e.g., to determine the day of the week or calculate `daysSince`), they are explicitly parsed as **UTC dates** (e.g., `new Date(\`${gameDay}T00:00:00Z\`)`). This ensures that date arithmetic (like finding the previous day) is consistent and avoids shifts due to the server's local timezone.
|
||
|
||
4. **Day-of-Week Convention:** The application adheres to a specific convention for days of the week:
|
||
* **Monday: `0`**
|
||
* Tuesday: `1`
|
||
* Wednesday: `2`
|
||
* Thursday: `3`
|
||
* Friday: `4`
|
||
* Saturday: `5`
|
||
* Sunday: `6`
|
||
|
||
### Example Usage:
|
||
|
||
* **`DailyVisit.date`**: Stores the "Game Day" on which a user's visit was recorded.
|
||
* **`HabitCompletion.date`**: Stores the "Game Day" on which a habit was marked as complete.
|
||
* **`Village.lastTickDay`**: Stores the "Game Day" (server-side determined) when the village's background progression was last processed, preventing redundant calculations within the same server day.
|
||
* **`VillageObject.lastExpDay`**: Stores the "Game Day" when an object (e.g., a field) last generated experience.
|
||
* **`VillageTile.clearingStartedDay`**: Stores the "Game Day" when a tile's clearing process began.
|
||
|
||
This consistent use of "Game Day" strings and client-provided dates (for user actions) combined with server-side UTC parsing (for calculations) provides a robust solution to managing time-based game mechanics across different timezones.
|
||
|
||
## 5. AI / Gemini Usage Rules
|
||
- **DO NOT** allow the AI to change the Node.js version, upgrade Prisma, alter the Prisma configuration, or modify the core project structure.
|
||
- **ALLOWED:** The AI can be used to add or modify Prisma schema models, generate new API endpoints, and implement business logic within the existing architectural framework.
|