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

170 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 neededprefer 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 (<button>, <nav>, <main>, <section>, <label>, 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
<!-- copilot: follow the repo instructions above -->
<script lang="ts">
let count = $state(0);
let doubled = $derived(count * 2);
$effect(() => console.log(`count is ${count}`));
</script>
<div class="rounded-lg border border-gray-300 p-4 flex flex-col gap-4">
<button
class="rounded-md px-4 py-2 bg-blue-600 text-white"
onclick={() => count++}
aria-label="Increment counter"
>
{count}
</button>
<p>{doubled}</p>
</div>
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