Files
vontor-cz/.github/copilot-instructions.md
David Bruno Vontor d94ad93222 Add choices API endpoint and OpenAPI client setup
Introduces a new /api/choices/ endpoint for fetching model choices with multilingual labels. Updates Django models to use 'cz#' prefix for Czech labels. Adds OpenAPI client generation via orval, refactors frontend API structure, and provides documentation and helper scripts for dynamic choices and OpenAPI usage.
2025-12-04 17:35:47 +01:00

5.7 KiB

Copilot Instructions for Vontor CZ

Overview

This monorepo contains a Django backend and a Vite/React frontend, orchestrated via Docker Compose. The project is designed for a Czech e-marketplace, with custom payment integrations and real-time features.

Architecture

  • backend/: Django project (vontor_cz), custom account app, and third-party payment integrations (thirdparty/).
    • Uses Django REST Framework, Channels (ASGI), Celery, and S3/static/media via django-storages.
    • Custom user model: account.CustomUser.
    • API docs: DRF Spectacular (/api/schema/).
  • frontend/: Vite + React + TypeScript app.
    • Organized by src/api/, components/, features/, layouts/, pages/, routes/.
    • Uses React Router layouts and nested routes (see src/layouts/, src/routes/).
    • Uses Tailwind CSS for styling (configured via src/index.css with @import "tailwindcss";). Prefer utility classes over custom CSS.

Developer Workflows

  • Backend
    • Local dev: python manage.py runserver (or use Docker Compose)
    • Migrations: python manage.py makemigrations && python manage.py migrate
    • Celery: celery -A vontor_cz worker -l info
    • Channels: Daphne/ASGI (see Docker Compose command)
    • Env config: .env files in backend/ (see .gitignore for secrets)
  • Frontend
    • Install: npm install
    • Dev server: npm run dev
    • Build: npm run build
    • Preview: npm run preview
    • Static assets: src/assets/ (import in JS/CSS), public/ (referenced in HTML)

Conventions & Patterns

  • Backend
    • Use environment variables for secrets and config (see settings.py).
    • Static/media files: S3 in production, local in dev (see settings.py).
    • API versioning and docs: DRF Spectacular config in settings.py.
    • Custom permissions, filters, and serializers in each app.
  • Frontend
    • Use React Router layouts for shared UI (see src/layouts/, LAYOUTS.md).
    • API calls and JWT handling in src/api/.
    • Route definitions and guards in src/routes/ (ROUTES.md).
    • Use TypeScript strict mode (see tsconfig.*.json).
    • Linting: ESLint config in eslint.config.js.
    • Styling: Tailwind CSS is present. Prefer utility classes; keep minimal component-scoped CSS. Global/base styles live in src/index.css. Avoid inline styles and CSS-in-JS unless necessary.

Frontend API Client (required)

All frontend API calls must use the shared client at frontend/src/api/Client.ts.

  • Client.public: no cookies, no Authorization header (for public Django endpoints).
  • Client.auth: sends cookies and includes Bearer token; auto-refreshes on 401 (retries up to 2x).
  • Centralized error handling: subscribe via Client.onError to show toasts/snackbars.
  • Tokens are stored in cookies by Client.setTokens and cleared by Client.clearTokens.

Example usage (TypeScript)

import Client from "@/api/Client";

// Public request (no credentials)
async function listPublicItems() {
  const res = await Client.public.get("/api/public/items/");
  return res.data;
}

// Login (obtain tokens and persist to cookies)
async function login(username: string, password: string) {
  // Default SimpleJWT endpoint (adjust if your backend differs)
  const res = await Client.public.post("/api/token/", { username, password });
  const { access, refresh } = res.data;
  Client.setTokens(access, refresh);
}

// Authenticated requests (auto Bearer + refresh on 401)
async function fetchProfile() {
  const res = await Client.auth.get("/api/users/me/");
  return res.data;
}

function logout() {
  Client.clearTokens();
  window.location.assign("/login");
}

// Global error toasts
import { useEffect } from "react";
function useApiErrors(showToast: (msg: string) => void) {
  useEffect(() => {
    const unsubscribe = Client.onError((e) => {
      const { message, status } = e.detail;
      showToast(status ? `${status}: ${message}` : message);
    });
    return unsubscribe;
  }, [showToast]);
}

Vite env used by the client:

  • VITE_API_BASE_URL (default: http://localhost:8000)
  • VITE_API_REFRESH_URL (default: /api/token/refresh/)
  • VITE_LOGIN_PATH (default: /login)

Notes

  • Public client never sends cookies or Authorization.
  • Ensure Django CORS settings allow your frontend origin. See backend/vontor_cz/settings.py.
  • Use React Router layouts and guards as documented in frontend/src/routes/ROUTES.md and frontend/src/layouts/LAYOUTS.md.

Integration Points

  • Payments: thirdparty/ contains custom integrations for Stripe, GoPay, Trading212.
  • Real-time: Django Channels (ASGI, Redis) for websockets.
  • Task queue: Celery + Redis for async/background jobs.
  • API: REST endpoints, JWT auth, API key support.

OpenAPI Client Generation

  • Schema: config = { schemaUrl: "/api/schema/", baseUrl: "/api/" }
  • Commands: npm run api:update (fetch schema + generate client)
  • Output: frontend/src/api/generated/ (TypeScript Axios client)
  • Axios instance: frontend/src/api/api.ts with withCredentials and JWT auto-refresh via existing Client.ts.
  • Choices helper: frontend/src/api/get_choices.tsgetChoices(requests, lang) returns { "Model.field": [{ value, label }] }.

References


When in doubt, check the referenced markdown files and settings.py for project-specific logic and patterns.