File size: 2,968 Bytes
5c98911
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
 * DB-INT-01: ๋น„๊ฐ€์—ญ ์›์žฅ ํŠธ๋ฆฌ๊ฑฐ ๋ฐ ๋ฉฑ๋“ฑ์„ฑ ์ œ์•ฝ ๊ฒ€์ฆ ์Šคํฌ๋ฆฝํŠธ
 *
 * ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” PostgreSQL ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜์–ด settlement_ledger ํ…Œ์ด๋ธ”์˜
 * ๋น„๊ฐ€์—ญ์„ฑ(Immutability)๊ณผ ๋ฉฑ๋“ฑ์„ฑ(Idempotency)์ด ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ณด์žฅ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
 *
 * ์•ˆ์ „์žฅ์น˜:
 * - ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹คํ–‰์„ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ psql ์„ธ์…˜์—์„œ
 *   SET app.carboany_test_mode = 'on';
 *   ์„ ๋จผ์ € ์ง€์ •ํ•œ ๋กœ์ปฌ/ํ…Œ์ŠคํŠธ DB์—์„œ๋งŒ ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.
 * - ๋ชจ๋“  ๋ณ€๊ฒฝ์€ ๋งˆ์ง€๋ง‰์— ROLLBACK ๋ฉ๋‹ˆ๋‹ค.
 */

BEGIN;

DO $$
BEGIN
    IF current_setting('app.carboany_test_mode', true) IS DISTINCT FROM 'on' THEN
        RAISE EXCEPTION
            'Refusing to run ledger integrity test without SET app.carboany_test_mode = on';
    END IF;
END $$;

-- 1. ํ…Œ์ŠคํŠธ์šฉ ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
INSERT INTO public.settlement_ledger (
    transaction_id, campaign_id, sender_id, sender_name, receiver_id, receiver_name,
    category, asset, amount, idempotency_key, previous_hash, entry_hash, description
) VALUES (
    'test_txn_001', NULL, 'sponsor-A', 'Sponsor A', 'citizen-001', 'John Doe',
    'POINT_REWARD', 'POINT', 1000.0, 'test_idemp_key_001', NULL, 'test_hash_001', 'Test Entry'
);

-- 2. UPDATE ์‹œ๋„ (์—๋Ÿฌ ๋ฐœ์ƒ ๊ธฐ๋Œ€)
DO $$
BEGIN
    BEGIN
        UPDATE public.settlement_ledger SET amount = 2000.0 WHERE idempotency_key = 'test_idemp_key_001';
        RAISE EXCEPTION 'Update should have been blocked by trigger';
    EXCEPTION WHEN raise_exception THEN
        IF SQLERRM NOT LIKE 'settlement_ledger is append-only:%' THEN
            RAISE;
        END IF;
        RAISE NOTICE 'SUCCESS: Update blocked as expected: %', SQLERRM;
    END;
END $$;

-- 3. DELETE ์‹œ๋„ (์—๋Ÿฌ ๋ฐœ์ƒ ๊ธฐ๋Œ€)
DO $$
BEGIN
    BEGIN
        DELETE FROM public.settlement_ledger WHERE idempotency_key = 'test_idemp_key_001';
        RAISE EXCEPTION 'Delete should have been blocked by trigger';
    EXCEPTION WHEN raise_exception THEN
        IF SQLERRM NOT LIKE 'settlement_ledger is append-only:%' THEN
            RAISE;
        END IF;
        RAISE NOTICE 'SUCCESS: Delete blocked as expected: %', SQLERRM;
    END;
END $$;

-- 4. ๋™์ผ Idempotency Key ์žฌ์‚ฝ์ž… ์‹œ๋„ (Unique Violation ๊ธฐ๋Œ€)
DO $$
BEGIN
    BEGIN
        INSERT INTO public.settlement_ledger (
            transaction_id, campaign_id, sender_id, sender_name, receiver_id, receiver_name,
            category, asset, amount, idempotency_key, previous_hash, entry_hash, description
        ) VALUES (
            'test_txn_002', NULL, 'sponsor-A', 'Sponsor A', 'citizen-001', 'John Doe',
            'POINT_REWARD', 'POINT', 1000.0, 'test_idemp_key_001', 'test_hash_001', 'test_hash_002', 'Duplicate Entry'
        );
        RAISE EXCEPTION 'Duplicate insert should have been blocked by unique constraint';
    EXCEPTION WHEN unique_violation THEN
        RAISE NOTICE 'SUCCESS: Duplicate insert blocked by unique constraint';
    END;
END $$;

ROLLBACK;