### API Client Usage Examples (JavaScript) Source: https://www.ratiotuta.com/docs/developer Demonstrates how to use the project's API client for various HTTP methods (GET, POST, PATCH, DELETE). It includes examples of automatic CSRF token inclusion for state-changing requests and basic error handling. ```javascript import { api, ApiError } from '@/lib/api-client' // GET request (no CSRF needed) const data = await api.get('/api/places') // POST request (CSRF auto-included) const newPlace = await api.post('/api/places', { name: 'New Store', currency: 'EUR' }) // PATCH request const updated = await api.patch('/api/places/123', { name: 'Updated Name' }) // DELETE request await api.delete('/api/places/123') // Error handling try { await api.post('/api/places', data) } catch (err) { if (err instanceof ApiError) { console.error(err.message, err.status) } } ``` -------------------------------- ### Deploy to Production with Vercel CLI Source: https://www.ratiotuta.com/docs/developer Instructions for deploying the project to production using the Vercel CLI. This involves installing the CLI, running the production deployment command, or configuring automatic deployments through a connected GitHub repository. Ensure all environment variables are set in the Vercel dashboard. ```bash # Install Vercel CLI npm i -g vercel # Deploy vercel --prod # Or connect GitHub repo for auto-deploys ``` -------------------------------- ### API Client Usage Source: https://www.ratiotuta.com/docs/developer Examples demonstrating how to use the API client for various request types and error handling. ```APIDOC ```javascript import { api, ApiError } from '@/lib/api-client' // GET request (no CSRF needed) const data = await api.get('/api/places') // POST request (CSRF auto-included) const newPlace = await api.post('/api/places', { name: 'New Store', currency: 'EUR' }) // PATCH request const updated = await api.patch('/api/places/123', { name: 'Updated Name' }) // DELETE request await api.delete('/api/places/123') // Error handling try { await api.post('/api/places', data) } catch (err) { if (err instanceof ApiError) { console.error(err.message, err.status) } } ``` ``` -------------------------------- ### Security Practices - Security Headers Source: https://www.ratiotuta.com/docs/developer Configuration for security-related HTTP headers. ```APIDOC ### Security Headers ```javascript // next.config.ts headers: [ { key: 'X-Frame-Options', value: 'SAMEORIGIN' }, { key: 'X-Content-Type-Options', value: 'nosniff' }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, { key: 'Permissions-Policy', value: 'geolocation=(), microphone=()' }, { key: 'Content-Security-Policy', value: "default-src 'self'; img-src 'self' data: https://*.amazonaws.com;" }, { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' } ] ``` ``` -------------------------------- ### Item Resource Endpoints Source: https://www.ratiotuta.com/docs/developer Endpoints for managing items, including listing and creating. ```APIDOC ## GET /api/items ### Description List all available items. ### Method GET ### Endpoint /api/items ### Response #### Success Response (200) - **items** (array) - An array of item objects. - **id** (string) - Item's unique identifier. - **name** (string) - Name of the item. - **price** (number) - Price of the item. ## POST /api/items ### Description Create a new item. Requires CSRF token. ### Method POST ### Endpoint /api/items ### Headers - **X-CSRF-Token** (string) - Required - CSRF token for verification. ### Request Body - **name** (string) - Required - Name of the new item. - **price** (number) - Required - Price of the new item. - **placeId** (string) - Required - The ID of the place where the item belongs. ### Response #### Success Response (200) - **id** (string) - The unique identifier of the newly created item. - **name** (string) - The name of the new item. - **price** (number) - The price of the new item. - **placeId** (string) - The ID of the place the item belongs to. ``` -------------------------------- ### Security Practices - Authentication & Sessions Source: https://www.ratiotuta.com/docs/developer Information on authentication, password handling, and session management. ```APIDOC ### Authentication & Sessions * **Password Hashing:** bcrypt with 12 rounds. * **Password Requirements:** 8-128 characters, complexity checks. * **Pwned Password Check:** k-Anonymity API integration. * **Session Cookies:** HttpOnly, Secure, SameSite=Strict, `__Host-` prefix. * **Session Storage:** iron-session with AES-256-GCM encryption. * **Email Verification:** Required for account activation. ``` -------------------------------- ### Place Resource Endpoints Source: https://www.ratiotuta.com/docs/developer Endpoints for managing places, including listing, creating, updating, and deleting. ```APIDOC ## GET /api/places ### Description List all available places. ### Method GET ### Endpoint /api/places ### Response #### Success Response (200) - **places** (array) - An array of place objects. - **id** (string) - Place's unique identifier. - **name** (string) - Name of the place. - **currency** (string) - Currency associated with the place. ## POST /api/places ### Description Create a new place. Requires CSRF token. ### Method POST ### Endpoint /api/places ### Headers - **X-CSRF-Token** (string) - Required - CSRF token for verification. ### Request Body - **name** (string) - Required - Name of the new place. - **currency** (string) - Required - Currency for the new place. ### Response #### Success Response (200) - **id** (string) - The unique identifier of the newly created place. - **name** (string) - The name of the new place. - **currency** (string) - The currency of the new place. ## PATCH /api/places/[id] ### Description Update an existing place. Requires CSRF token. ### Method PATCH ### Endpoint /api/places/[id] ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the place to update. ### Headers - **X-CSRF-Token** (string) - Required - CSRF token for verification. ### Request Body - **name** (string) - Optional - The updated name of the place. - **currency** (string) - Optional - The updated currency for the place. ### Response #### Success Response (200) - **message** (string) - Success message indicating the place was updated. ## DELETE /api/places/[id] ### Description Delete a place. Requires CSRF token. ### Method DELETE ### Endpoint /api/places/[id] ### Parameters #### Path Parameters - **id** (string) - Required - The unique identifier of the place to delete. ### Headers - **X-CSRF-Token** (string) - Required - CSRF token for verification. ### Response #### Success Response (200) - **message** (string) - Success message indicating the place was deleted. ``` -------------------------------- ### Authentication Endpoints Source: https://www.ratiotuta.com/docs/developer Endpoints for user authentication, including login, registration, and logout. ```APIDOC ## POST /api/login ### Description Login with email & password. Returns user data and sets session cookie. ### Method POST ### Endpoint /api/login ### Request Body - **email** (string) - Required - User's email address. - **password** (string) - Required - User's password. - **remember** (boolean) - Optional - Whether to remember the user. ### Request Example ```json { "email": "user@example.com", "password": "***", "remember": true } ``` ### Response #### Success Response (200) - **id** (string) - User's unique identifier. - **email** (string) - User's email address. - **role** (string) - User's role. #### Response Example ```json { "id": "...", "email": "...", "role": "USER" } ``` ## POST /api/register/self ### Description Register new user account. Sends verification email. ### Method POST ### Endpoint /api/register/self ### Request Body - **name** (string) - Required - User's full name. - **email** (string) - Required - User's email address. - **password** (string) - Required - User's chosen password. - **teamName** (string) - Optional - The name of the team the user is joining. ### Request Example ```json { "name": "John Doe", "email": "...", "password": "...", "teamName": "..." } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating account creation and email verification prompt. #### Response Example ```json { "message": "Account created. Please verify your email." } ``` ## POST /api/logout ### Description End session and clear cookies. Requires CSRF token. ### Method POST ### Endpoint /api/logout ### Headers - **X-CSRF-Token** (string) - Required - CSRF token for verification. ``` -------------------------------- ### User Resource Endpoints Source: https://www.ratiotuta.com/docs/developer Endpoints for managing the current user's profile and account. ```APIDOC ## GET /api/users/me ### Description Get current user's profile information. ### Method GET ### Endpoint /api/users/me ### Response #### Success Response (200) - **id** (string) - User's unique identifier. - **name** (string) - User's full name. - **email** (string) - User's email address. - **role** (string) - User's role. ## PATCH /api/users/me ### Description Update the current user's profile information. Requires CSRF token. ### Method PATCH ### Endpoint /api/users/me ### Headers - **X-CSRF-Token** (string) - Required - CSRF token for verification. ### Request Body - **name** (string) - Optional - Updated user name. - **email** (string) - Optional - Updated user email. ### Response #### Success Response (200) - **message** (string) - Success message indicating profile update. ## DELETE /api/users/me ### Description Delete the current user's account. Requires CSRF token. ### Method DELETE ### Endpoint /api/users/me ### Headers - **X-CSRF-Token** (string) - Required - CSRF token for verification. ### Response #### Success Response (200) - **message** (string) - Success message indicating account deletion. ``` -------------------------------- ### Receipt Resource Endpoints Source: https://www.ratiotuta.com/docs/developer Endpoint for creating receipts. ```APIDOC ## POST /api/receipts ### Description Create a new receipt. Requires CSRF token. ### Method POST ### Endpoint /api/receipts ### Headers - **X-CSRF-Token** (string) - Required - CSRF token for verification. ### Request Body - **items** (array) - Required - An array of items included in the receipt. - **itemId** (string) - Required - The ID of the item. - **quantity** (number) - Required - The quantity of the item. - **placeId** (string) - Required - The ID of the place the receipt is associated with. ### Response #### Success Response (200) - **id** (string) - The unique identifier of the newly created receipt. - **totalAmount** (number) - The total amount of the receipt. - **createdAt** (string) - The timestamp when the receipt was created. ``` -------------------------------- ### Prisma Database Operations - npm Scripts Source: https://www.ratiotuta.com/docs/developer Collection of npm scripts for managing the Prisma database, including running migrations, generating the Prisma Client, opening Prisma Studio, and resetting the database for development. ```bash // Run migrations npm run prisma:migrate // Generate Prisma Client npm run prisma:generate // Open Prisma Studio (GUI) npm run prisma:studio // Reset database (development only!) npm run prisma:reset ``` -------------------------------- ### Database Migrations with Prisma Source: https://www.ratiotuta.com/docs/developer This snippet shows the command to apply database migrations using Prisma. It assumes you have Prisma set up and configured for your PostgreSQL database. Run this command after setting up your database and ensuring the `DATABASE_URL` environment variable is correctly configured. ```bash # Use Vercel Postgres, Supabase, or any PostgreSQL provider # Run migrations npx prisma migrate deploy ``` -------------------------------- ### Security Practices - Rate Limiting Source: https://www.ratiotuta.com/docs/developer Details on the API's rate limiting strategy. ```APIDOC ### Rate Limiting * **Authentication:** 5 attempts per 15 minutes per IP. * **API Endpoints:** Sliding window algorithm. * **Storage:** Upstash Redis (distributed). * **Response Headers:** `X-RateLimit-*` for debugging. ``` -------------------------------- ### Security Practices - Data Protection Source: https://www.ratiotuta.com/docs/developer Details on data encryption at rest and file storage practices. ```APIDOC ### Data Protection #### Email Encryption * AES-256-GCM at rest. * HMAC-SHA256 for lookups. * Prevents data breach exposure. #### File Storage * AWS S3 with signed URLs. * 5MB max file size. * MIME type validation. ``` -------------------------------- ### Configure Essential Environment Variables for Production Source: https://www.ratiotuta.com/docs/developer This section lists the required environment variables for deploying the Ratio Tuta project. These include database connection URLs, secrets for sessions and AWS S3, API keys for email services, Redis connection details for rate limiting, and application URLs. These should be securely managed and set in the `.env.example` file and the deployment environment. ```dotenv # Database DATABASE_URL="postgresql://..." # Sessions SESSION_SECRET="strong-random-secret-min-32-chars" # AWS S3 (file uploads) AWS_ACCESS_KEY_ID="..." AWS_SECRET_ACCESS_KEY="..." AWS_REGION="us-east-1" AWS_S3_BUCKET="ratio-tuta-files" # Email (Resend) RESEND_API_KEY="re_..." RESEND_FROM_EMAIL="noreply@yourdomain.com" # Redis (rate limiting) UPSTASH_REDIS_REST_URL="https://..." UPSTASH_REDIS_REST_TOKEN="..." # App NEXT_PUBLIC_APP_URL="https://yourdomain.com" NODE_ENV="production" ``` -------------------------------- ### Security Headers Configuration (Next.js) Source: https://www.ratiotuta.com/docs/developer Defines security headers for a Next.js application to enhance protection against various web vulnerabilities like clickjacking, MIME-sniffing, and cross-site scripting. ```javascript // next.config.ts headers: [ { key: 'X-Frame-Options', value: 'SAMEORIGIN' }, { key: 'X-Content-Type-Options', value: 'nosniff' }, { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' }, { key: 'Permissions-Policy', value: 'geolocation=(), microphone=()' }, { key: 'Content-Security-Policy', value: "default-src 'self'; img-src 'self' data: https://*.amazonaws.com;" }, { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' } ] ``` -------------------------------- ### Project Structure for Ratio Tuta Source: https://www.ratiotuta.com/docs/developer This snippet illustrates the directory structure of the Ratio Tuta project, organized for Next.js 15 with a clear separation of concerns for app logic, components, libraries, and database schema. ```tree ratio-tuta/ ├── src/ │ ├── app/ # Next.js 15 App Router │ │ ├── api/ # API endpoints │ │ ├── auth/ # Authentication pages │ │ ├── dashboard/ # Admin dashboard │ │ ├── cash-register/ # POS interface │ │ └── docs/ # Documentation │ ├── components/ # React components │ │ ├── admin-zone/ # Admin UI components │ │ ├── cash-register/ # POS components │ │ └── ui/ # Reusable UI elements │ ├── lib/ # Utility libraries │ │ ├── api-client.ts # CSRF-enabled API wrapper │ │ ├── auth.ts # Authentication helpers │ │ ├── csrf.ts # CSRF token generation │ │ ├── session.ts # Session management │ │ └── prisma.ts # Database client │ └── hooks/ # Custom React hooks ├── prisma/ │ └── schema.prisma # Database schema ├── lib/ # Shared backend utilities ├── public/ # Static assets └── messages/ # i18n translations ``` -------------------------------- ### Security Practices - CSRF Protection Source: https://www.ratiotuta.com/docs/developer Details on the Cross-Site Request Forgery (CSRF) protection mechanism. ```APIDOC ### CSRF Protection **Implementation:** Stateless HMAC-based tokens tied to user sessions * Token format: `randomValue.hmac(randomValue:userId)` * No server-side storage required * Timing-safe token comparison (prevents timing attacks) * Auto-included in all state-changing requests (POST, PUT, PATCH, DELETE) #### Backend Validation Example ```javascript import { requireCsrfToken } from '@lib/csrf' export async function POST(req: Request) { const session = await getSession() requireCsrfToken(req, session) // Throws if invalid // ... handle request } ``` ``` -------------------------------- ### Prisma Schema - Receipt and ReceiptLineItem Models Source: https://www.ratiotuta.com/docs/developer Defines the Receipt and ReceiptLineItem models for recording sales transactions. Includes details on the total amount, payment, and individual items purchased. ```prisma model Receipt { id String @id @default(cuid()) placeId String userId String totalAmount Float taxAmount Float amountGiven Float changeAmount Float paymentOption PaymentOption lineItems ReceiptLineItem[] createdAt DateTime @default(now()) } model ReceiptLineItem { id String @id @default(cuid()) receiptId String itemId String quantity Float unitPrice Float totalPrice Float taxRateBps Int } ``` -------------------------------- ### Prisma Schema - User Model Source: https://www.ratiotuta.com/docs/developer Defines the User model with fields for authentication, personal information, and role. Includes security measures like encrypted emails and HMAC indexing for lookups. ```prisma model User { id String @id @default(cuid()) email String @unique emailHmac String @unique // HMAC for lookups emailEncrypted String // AES-256-GCM encrypted passwordHash String firstName String lastName String role Role @default(USER) emailVerified Boolean @default(false) avatarUrl String? createdAt DateTime @default(now()) } ``` -------------------------------- ### CSRF Protection Backend Validation (TypeScript) Source: https://www.ratiotuta.com/docs/developer Illustrates how to implement backend CSRF token validation using the `requireCsrfToken` function. This ensures that state-changing requests are legitimate. ```typescript import { requireCsrfToken } from '@lib/csrf' export async function POST(req: Request) { const session = await getSession() requireCsrfToken(req, session) // Throws if invalid // ... handle request } ``` -------------------------------- ### Prisma Schema - Item Model Source: https://www.ratiotuta.com/docs/developer Defines the Item model for products or services, including pricing, tax information, measurement types, and stock quantity. Associated with a team for inventory management. ```prisma model Item { id String @id @default(cuid()) teamId String name String sku String? price Float pricePaid Float? taxRateBps Int // Basis points (100 = 1%) imageUrl String measurementType MeasurementType @default(PCS) stockQuantity Float @default(0) categoryId String? isActive Boolean @default(true) } ``` -------------------------------- ### Log Security-Sensitive Actions with Audit Logging Source: https://www.ratiotuta.com/docs/developer This snippet demonstrates how to log security-sensitive actions using the `@lib/logger` module. It takes an audit object with properties like action, status, userId, and metadata. Ensure the logger is properly configured to capture these events for security monitoring. ```javascript import { logAudit } from '@lib/logger' await logAudit({ action: 'user.login.success', status: 'SUCCESS', userId: user.id, metadata: { ip: req.ip } }) ``` -------------------------------- ### Prisma Schema - Team and TeamMember Models Source: https://www.ratiotuta.com/docs/developer Defines the Team and TeamMember models for managing multi-tenancy and user roles within teams. Ensures data separation and security through team-based isolation. ```prisma model Team { id String @id @default(cuid()) name String ownerId String members TeamMember[] places Place[] items Item[] plan SubscriptionPlan @default(FREE) } model TeamMember { id String @id @default(cuid()) teamId String userId String role TeamRole @default(MEMBER) } ``` -------------------------------- ### Prisma Schema - Place Model Source: https://www.ratiotuta.com/docs/developer Defines the Place model representing a physical location, including its association with a team, address details, and active status. Used for tracking locations where receipts are generated. ```prisma model Place { id String @id @default(cuid()) teamId String name String address1 String? city String? country String? timezone String? currency String @default("EUR") isActive Boolean @default(true) receipts Receipt[] createdAt DateTime @default(now()) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.