Files
scan-wave/.github/copilot-instructions.md
2025-07-02 21:50:45 +02:00

5.7 KiB
Raw Blame History

GitHub Copilot Instructions for This Repository Use Svelte 5 runes exclusively

Declare reactive state with $state(); derive values with $derived(); run side-effect logic with $effect() etc. svelte.dev svelte.dev

Do not fall back to the legacy $: label syntax or Svelte 3/4 stores! This is important!

Enforce a clean component structure

<script> comes first, followed by markup and then an optional <style> (rarely needed—prefer Tailwind). Export component props with export let … (still valid in Svelte 5). Keep each component focused on one visual/behavioural concern; split larger UIs into children. Tailwind-only styling conventions Base container: rounded-lg border border-gray-300 (or rounded-md on small items). Absolutely no shadow-* classes. Use p-4 or p-6 for internal padding, and gap-* utilities (not margin hacks) for spacing between children. Prefer neutral greys (gray-50gray-800) and a single accent palette defined in tailwind.config.js. HTML & accessibility Generate semantic elements (, , ,
, , etc.). Every interactive element must have an accessible name (aria-label, visible text, or title). Do not generate tabindex gymnastics; rely on natural DOM order. Type safety & tooling Default to <script lang="ts"> unless the file is explicitly plain JS. Always import types from @types/svelte or svelte where needed. File / folder conventions Component names are PascalCase.svelte. Collocate tests as ComponentName.test.ts beside the component. Put shared util functions in src/lib. Example pattern (reference only) svelte Copy Edit <script lang="ts"> let count = $state(0); let doubled = $derived(count * 2); $effect(() => console.log(`count is ${count}`)); </script>
count++} aria-label="Increment counter" > {count}

{doubled}

What not to do

No inline style="" attributes.

No external CSS files unless Tailwind cannot express the rule.

No class names that imply design debt (.box, .wrapper, .container-1, etc.).

Avoid non-reactive variables; if a value affects the UI, use a rune.

NEVER $: label syntax; use $state(), $derived(), and $effect().

If you want to use supabse client in the browser, it is stored in the data variable obtained from let { data } = $props();

Using on:click to listen to the click event is deprecated. Use the event attribute onclick instead

onsubmit|preventDefault={handleSubmit} is depracated, do not use it!

Loading session using page.server.ts is not needed as the session is already available in the locals object.

The database schema in supabase is as follows: -- WARNING: This schema is for context only and is not meant to be run. -- Table order and constraints may not be valid for execution.

CREATE TABLE public.events ( id uuid NOT NULL DEFAULT gen_random_uuid(), created_at timestamp with time zone NOT NULL DEFAULT now(), created_by uuid DEFAULT auth.uid(), name text, date date, section_id uuid, email_subject text, email_body text, sheet_id text, name_column numeric, surname_column numeric, email_column numeric, confirmation_column numeric, CONSTRAINT events_pkey PRIMARY KEY (id), CONSTRAINT events_created_by_fkey FOREIGN KEY (created_by) REFERENCES auth.users(id), CONSTRAINT events_section_id_fkey FOREIGN KEY (section_id) REFERENCES public.sections(id) ); CREATE TABLE public.events_archived ( id uuid NOT NULL DEFAULT gen_random_uuid(), created_at timestamp with time zone NOT NULL DEFAULT now(), date date, name text NOT NULL, total_participants numeric, scanned_participants numeric, section_id uuid, CONSTRAINT events_archived_pkey PRIMARY KEY (id), CONSTRAINT events_archived_section_id_fkey FOREIGN KEY (section_id) REFERENCES public.sections(id) ); CREATE TABLE public.participants ( id uuid NOT NULL DEFAULT gen_random_uuid(), created_at timestamp with time zone NOT NULL DEFAULT now(), created_by uuid DEFAULT auth.uid(), event uuid, name text, surname text, email text, scanned boolean DEFAULT false, scanned_at timestamp with time zone, scanned_by uuid, section_id uuid, CONSTRAINT participants_pkey PRIMARY KEY (id), CONSTRAINT participants_created_by_fkey FOREIGN KEY (created_by) REFERENCES auth.users(id), CONSTRAINT participants_event_fkey FOREIGN KEY (event) REFERENCES public.events(id), CONSTRAINT participants_scanned_by_fkey FOREIGN KEY (scanned_by) REFERENCES public.profiles(id), CONSTRAINT qrcodes_scanned_by_fkey FOREIGN KEY (scanned_by) REFERENCES auth.users(id), CONSTRAINT qrcodes_section_id_fkey FOREIGN KEY (section_id) REFERENCES public.sections(id) ); CREATE TABLE public.profiles ( id uuid NOT NULL, display_name text, created_at timestamp with time zone DEFAULT now(), updated_at timestamp with time zone DEFAULT now(), section_id uuid, section_position USER-DEFINED NOT NULL DEFAULT 'member'::section_posititon, CONSTRAINT profiles_pkey PRIMARY KEY (id), CONSTRAINT profiles_id_fkey FOREIGN KEY (id) REFERENCES auth.users(id), CONSTRAINT profiles_section_id_fkey FOREIGN KEY (section_id) REFERENCES public.sections(id) ); CREATE TABLE public.sections ( id uuid NOT NULL DEFAULT gen_random_uuid(), created_at timestamp with time zone NOT NULL DEFAULT now(), name text NOT NULL UNIQUE, CONSTRAINT sections_pkey PRIMARY KEY (id) );

An event is created by calling RPC databse function create_event by passing the following parameters:

  • name, date, email_subject, email_body, sheet_id, name_column, surname_column, email_column, confirmation_column