feat: remove AI extensions, restructure settings, and add atomic voucher commits (#157)
Remove AI-dependent extensions (ai-chat, ai-categorization, receipt-ocr, invoice-inbox) and their infrastructure (lib/ai/*, ai-consent, LangChain/ Anthropic/OpenAI deps) to simplify core and reduce bundle size. Restructure monolithic settings page into dedicated sub-pages (company, bookkeeping, invoicing, tax, banking, api, account, team, templates) with shared layout and sidebar navigation. Add atomic commit_journal_entry RPC so voucher number increment and status update happen in a single transaction — prevents burned numbers on constraint failures. Add continuity check report and voucher gap explanation tracking. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e89f2c402d
commit
d0b3f21bde
@@ -0,0 +1,54 @@
|
||||
-- Atomic journal entry commit: assigns voucher number and posts entry in one transaction.
|
||||
-- Prevents burned voucher numbers from failed commits (the counter increment rolls back
|
||||
-- if the status update or balance trigger fails).
|
||||
--
|
||||
-- Only used for the draft→posted transition (commitEntry). reverseEntry and storno
|
||||
-- use a different flow (INSERT with voucher number) and still call next_voucher_number.
|
||||
CREATE OR REPLACE FUNCTION public.commit_journal_entry(
|
||||
p_company_id uuid,
|
||||
p_entry_id uuid
|
||||
)
|
||||
RETURNS TABLE (voucher_number integer)
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
v_next integer;
|
||||
v_fiscal_period_id uuid;
|
||||
v_series text;
|
||||
BEGIN
|
||||
-- Fetch and lock the draft entry
|
||||
SELECT je.fiscal_period_id, COALESCE(je.voucher_series, 'A')
|
||||
INTO v_fiscal_period_id, v_series
|
||||
FROM public.journal_entries je
|
||||
WHERE je.id = p_entry_id
|
||||
AND je.company_id = p_company_id
|
||||
AND je.status = 'draft'
|
||||
FOR UPDATE;
|
||||
|
||||
IF NOT FOUND THEN
|
||||
RAISE EXCEPTION 'Draft journal entry not found: %', p_entry_id;
|
||||
END IF;
|
||||
|
||||
-- Increment voucher sequence (atomic via INSERT ON CONFLICT)
|
||||
INSERT INTO public.voucher_sequences (company_id, user_id, fiscal_period_id, voucher_series, last_number)
|
||||
VALUES (p_company_id, auth.uid(), v_fiscal_period_id, v_series, 1)
|
||||
ON CONFLICT (company_id, fiscal_period_id, voucher_series)
|
||||
DO UPDATE SET
|
||||
last_number = public.voucher_sequences.last_number + 1,
|
||||
updated_at = now()
|
||||
RETURNING last_number INTO v_next;
|
||||
|
||||
-- Update entry to posted with the assigned voucher number.
|
||||
-- If the balance trigger (check_balance_on_post) rejects the UPDATE,
|
||||
-- the entire transaction rolls back — including the sequence increment.
|
||||
-- No burned number, no gap.
|
||||
UPDATE public.journal_entries
|
||||
SET voucher_number = v_next,
|
||||
status = 'posted'
|
||||
WHERE id = p_entry_id
|
||||
AND company_id = p_company_id;
|
||||
|
||||
RETURN QUERY SELECT v_next;
|
||||
END;
|
||||
$$;
|
||||
Reference in New Issue
Block a user