@gelabs/ovr 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/chunk-3KIDW4LT.js +13 -0
  2. package/dist/chunk-4SZXBT56.js +26 -0
  3. package/dist/chunk-55FQP2DO.js +46 -0
  4. package/dist/{chunk-JV7QQ22Q.js → chunk-5YYR37CF.js} +10 -1
  5. package/dist/chunk-5Z2IAD5I.js +72 -0
  6. package/dist/chunk-BBQBKQA4.js +31 -0
  7. package/dist/chunk-BIQ2J75Y.js +54 -0
  8. package/dist/chunk-E2D7QT6N.js +92 -0
  9. package/dist/chunk-EGKFELO3.js +15 -0
  10. package/dist/chunk-EYFZWQ4J.js +74 -0
  11. package/dist/chunk-GDOCD7LT.js +46 -0
  12. package/dist/chunk-IF5UAVIE.js +25 -0
  13. package/dist/chunk-JEYT63LE.js +25 -0
  14. package/dist/chunk-K3KIBHJF.js +20 -0
  15. package/dist/chunk-M35R6JLA.js +142 -0
  16. package/dist/chunk-MDTRBOPQ.js +22 -0
  17. package/dist/chunk-NSCIBSCW.js +24 -0
  18. package/dist/chunk-OE525ZER.js +31 -0
  19. package/dist/chunk-OWCGEEAZ.js +107 -0
  20. package/dist/chunk-QCRVT2SS.js +18 -0
  21. package/dist/chunk-SETIN6XP.js +95 -0
  22. package/dist/chunk-WOPU6DI7.js +77 -0
  23. package/dist/chunk-XQTVSNHC.js +18 -0
  24. package/dist/core-i18n.d.ts +2 -2
  25. package/dist/core-i18n.js +1 -1
  26. package/dist/data-db.d.ts +1 -4
  27. package/dist/data-mock-store.js +53 -1
  28. package/dist/data-prisma-store.d.ts +3 -1
  29. package/dist/data-prisma-store.js +84 -1
  30. package/dist/data-seed-runner.d.ts +2 -1
  31. package/dist/data.d.ts +13 -1
  32. package/dist/offline.d.ts +126 -0
  33. package/dist/offline.js +376 -0
  34. package/dist/{types-DrrNO_Ak.d.ts → types-CtBC5-TW.d.ts} +8 -0
  35. package/dist/ui-components-admin/admin-nav.d.ts +7 -0
  36. package/dist/ui-components-admin/admin-nav.js +83 -0
  37. package/dist/ui-components-admin/issuance-form.d.ts +15 -0
  38. package/dist/ui-components-admin/issuance-form.js +367 -0
  39. package/dist/ui-components-admin/stat-card.d.ts +10 -0
  40. package/dist/ui-components-admin/stat-card.js +29 -0
  41. package/dist/ui-components-admin/ticket-preview.d.ts +9 -0
  42. package/dist/ui-components-admin/ticket-preview.js +13 -0
  43. package/dist/ui-components-admin/tickets-table.d.ts +8 -0
  44. package/dist/ui-components-admin/tickets-table.js +50 -0
  45. package/dist/ui-components-citizen/citizen-nav.d.ts +5 -0
  46. package/dist/ui-components-citizen/citizen-nav.js +33 -0
  47. package/dist/ui-components-citizen/payment-form.d.ts +14 -0
  48. package/dist/ui-components-citizen/payment-form.js +168 -0
  49. package/dist/ui-components-citizen/payment-qr-dialog.d.ts +30 -0
  50. package/dist/ui-components-citizen/payment-qr-dialog.js +9 -0
  51. package/dist/ui-components-citizen/ticket-not-found.d.ts +5 -0
  52. package/dist/ui-components-citizen/ticket-not-found.js +21 -0
  53. package/dist/ui-components-citizen/violation-history-table.d.ts +16 -0
  54. package/dist/ui-components-citizen/violation-history-table.js +77 -0
  55. package/dist/ui-components-shared/amount-summary.d.ts +8 -0
  56. package/dist/ui-components-shared/amount-summary.js +7 -0
  57. package/dist/ui-components-shared/money.d.ts +9 -0
  58. package/dist/ui-components-shared/money.js +5 -0
  59. package/dist/ui-components-shared/municipal-seal.d.ts +11 -0
  60. package/dist/ui-components-shared/municipal-seal.js +6 -0
  61. package/dist/ui-components-shared/official-header.d.ts +5 -0
  62. package/dist/ui-components-shared/official-header.js +7 -0
  63. package/dist/ui-components-shared/print-button.d.ts +8 -0
  64. package/dist/ui-components-shared/print-button.js +17 -0
  65. package/dist/ui-components-shared/seal.d.ts +12 -0
  66. package/dist/ui-components-shared/seal.js +2 -0
  67. package/dist/ui-components-shared/site-header.d.ts +13 -0
  68. package/dist/ui-components-shared/site-header.js +40 -0
  69. package/dist/ui-components-shared/sonner.d.ts +6 -0
  70. package/dist/ui-components-shared/sonner.js +38 -0
  71. package/dist/ui-components-shared/status-badge.d.ts +9 -0
  72. package/dist/ui-components-shared/status-badge.js +3 -0
  73. package/dist/ui-components-shared/theme-toggle.d.ts +7 -0
  74. package/dist/ui-components-shared/theme-toggle.js +6 -0
  75. package/dist/ui-components-shared/ticket-receipt.d.ts +12 -0
  76. package/dist/ui-components-shared/ticket-receipt.js +158 -0
  77. package/dist/ui-components-shared/violations-table.d.ts +8 -0
  78. package/dist/ui-components-shared/violations-table.js +7 -0
  79. package/dist/ui-components-ui/alert.js +2 -74
  80. package/dist/ui-components-ui/badge.d.ts +1 -1
  81. package/dist/ui-components-ui/badge.js +2 -46
  82. package/dist/ui-components-ui/button.d.ts +2 -2
  83. package/dist/ui-components-ui/card.js +2 -95
  84. package/dist/ui-components-ui/checkbox.js +2 -31
  85. package/dist/ui-components-ui/dialog.js +3 -142
  86. package/dist/ui-components-ui/input.js +2 -20
  87. package/dist/ui-components-ui/label.js +2 -18
  88. package/dist/ui-components-ui/separator.js +2 -24
  89. package/dist/ui-components-ui/skeleton.js +2 -15
  90. package/dist/ui-components-ui/table.js +2 -107
  91. package/dist/ui-components-ui/textarea.js +2 -18
  92. package/dist/ui-config.d.ts +19 -2
  93. package/dist/ui-config.js +2 -36
  94. package/dist/ui-server.d.ts +1 -1
  95. package/dist/ui-server.js +1 -1
  96. package/package.json +24 -4
  97. package/prisma/migrations/20260611112111_init/migration.sql +142 -0
  98. package/prisma/migrations/20260611112121_add_ticket_sequence/migration.sql +4 -0
  99. package/prisma/migrations/20260612000000_split_violator_address/migration.sql +26 -0
  100. package/prisma/migrations/20260612000100_barangay_optional/migration.sql +2 -0
  101. package/prisma/migrations/migration_lock.toml +3 -0
@@ -1,25 +1,3 @@
1
1
  "use client";
2
- import { cn } from '../chunk-77QBZC7J.js';
3
- import { Separator as Separator$1 } from '@base-ui/react/separator';
4
- import { jsx } from 'react/jsx-runtime';
5
-
6
- function Separator({
7
- className,
8
- orientation = "horizontal",
9
- ...props
10
- }) {
11
- return /* @__PURE__ */ jsx(
12
- Separator$1,
13
- {
14
- "data-slot": "separator",
15
- orientation,
16
- className: cn(
17
- "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
18
- className
19
- ),
20
- ...props
21
- }
22
- );
23
- }
24
-
25
- export { Separator };
2
+ export { Separator } from '../chunk-NSCIBSCW.js';
3
+ import '../chunk-77QBZC7J.js';
@@ -1,15 +1,2 @@
1
- import { cn } from '../chunk-77QBZC7J.js';
2
- import { jsx } from 'react/jsx-runtime';
3
-
4
- function Skeleton({ className, ...props }) {
5
- return /* @__PURE__ */ jsx(
6
- "div",
7
- {
8
- "data-slot": "skeleton",
9
- className: cn("animate-pulse rounded-md bg-muted", className),
10
- ...props
11
- }
12
- );
13
- }
14
-
15
- export { Skeleton };
1
+ export { Skeleton } from '../chunk-EGKFELO3.js';
2
+ import '../chunk-77QBZC7J.js';
@@ -1,108 +1,3 @@
1
1
  "use client";
2
- import { cn } from '../chunk-77QBZC7J.js';
3
- import { jsx } from 'react/jsx-runtime';
4
-
5
- function Table({ className, ...props }) {
6
- return /* @__PURE__ */ jsx(
7
- "div",
8
- {
9
- "data-slot": "table-container",
10
- className: "relative w-full overflow-x-auto",
11
- children: /* @__PURE__ */ jsx(
12
- "table",
13
- {
14
- "data-slot": "table",
15
- className: cn("w-full caption-bottom text-sm", className),
16
- ...props
17
- }
18
- )
19
- }
20
- );
21
- }
22
- function TableHeader({ className, ...props }) {
23
- return /* @__PURE__ */ jsx(
24
- "thead",
25
- {
26
- "data-slot": "table-header",
27
- className: cn("[&_tr]:border-b", className),
28
- ...props
29
- }
30
- );
31
- }
32
- function TableBody({ className, ...props }) {
33
- return /* @__PURE__ */ jsx(
34
- "tbody",
35
- {
36
- "data-slot": "table-body",
37
- className: cn("[&_tr:last-child]:border-0", className),
38
- ...props
39
- }
40
- );
41
- }
42
- function TableFooter({ className, ...props }) {
43
- return /* @__PURE__ */ jsx(
44
- "tfoot",
45
- {
46
- "data-slot": "table-footer",
47
- className: cn(
48
- "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
49
- className
50
- ),
51
- ...props
52
- }
53
- );
54
- }
55
- function TableRow({ className, ...props }) {
56
- return /* @__PURE__ */ jsx(
57
- "tr",
58
- {
59
- "data-slot": "table-row",
60
- className: cn(
61
- "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
62
- className
63
- ),
64
- ...props
65
- }
66
- );
67
- }
68
- function TableHead({ className, ...props }) {
69
- return /* @__PURE__ */ jsx(
70
- "th",
71
- {
72
- "data-slot": "table-head",
73
- className: cn(
74
- "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
75
- className
76
- ),
77
- ...props
78
- }
79
- );
80
- }
81
- function TableCell({ className, ...props }) {
82
- return /* @__PURE__ */ jsx(
83
- "td",
84
- {
85
- "data-slot": "table-cell",
86
- className: cn(
87
- "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
88
- className
89
- ),
90
- ...props
91
- }
92
- );
93
- }
94
- function TableCaption({
95
- className,
96
- ...props
97
- }) {
98
- return /* @__PURE__ */ jsx(
99
- "caption",
100
- {
101
- "data-slot": "table-caption",
102
- className: cn("mt-4 text-sm text-muted-foreground", className),
103
- ...props
104
- }
105
- );
106
- }
107
-
108
- export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
2
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from '../chunk-OWCGEEAZ.js';
3
+ import '../chunk-77QBZC7J.js';
@@ -1,18 +1,2 @@
1
- import { cn } from '../chunk-77QBZC7J.js';
2
- import { jsx } from 'react/jsx-runtime';
3
-
4
- function Textarea({ className, ...props }) {
5
- return /* @__PURE__ */ jsx(
6
- "textarea",
7
- {
8
- "data-slot": "textarea",
9
- className: cn(
10
- "flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
11
- className
12
- ),
13
- ...props
14
- }
15
- );
16
- }
17
-
18
- export { Textarea };
1
+ export { Textarea } from '../chunk-QCRVT2SS.js';
2
+ import '../chunk-77QBZC7J.js';
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { b as OvrConfig } from './schema-CdsFQxIg.js';
3
3
  import { a as Formatters } from './format-C7MSwUHK.js';
4
- import { D as Dictionary } from './types-DrrNO_Ak.js';
4
+ import { D as Dictionary } from './types-CtBC5-TW.js';
5
5
  import 'zod';
6
6
  import './types.js';
7
7
 
@@ -20,4 +20,21 @@ declare function useOvrConfig(): OvrConfig;
20
20
  declare function useCopy(): Dictionary;
21
21
  declare function useFormatters(): Formatters;
22
22
 
23
- export { OvrConfigProvider, useCopy, useFormatters, useOvrConfig };
23
+ type Theme = "light" | "dark" | "system";
24
+ type Resolved = "light" | "dark";
25
+ interface ThemeContextValue {
26
+ theme: Theme;
27
+ resolvedTheme: Resolved;
28
+ setTheme: (theme: Theme) => void;
29
+ }
30
+ /**
31
+ * Minimal theme provider (light/dark/system). It renders NO client-side `<script>`
32
+ * — the no-flash script lives in the server-rendered root layout — so React 19
33
+ * never warns about a script rendered inside a client component.
34
+ */
35
+ declare function ThemeProvider({ children }: {
36
+ children: React.ReactNode;
37
+ }): React.JSX.Element;
38
+ declare function useTheme(): ThemeContextValue;
39
+
40
+ export { OvrConfigProvider, ThemeProvider, useCopy, useFormatters, useOvrConfig, useTheme };
package/dist/ui-config.js CHANGED
@@ -1,37 +1,3 @@
1
1
  "use client";
2
- import { createFormatters } from './chunk-B634JHKZ.js';
3
- import * as React from 'react';
4
- import { jsx } from 'react/jsx-runtime';
5
-
6
- var OvrConfigContext = React.createContext(null);
7
- function OvrConfigProvider({
8
- config,
9
- copy,
10
- children
11
- }) {
12
- const value = React.useMemo(
13
- () => ({ config, copy, formatters: createFormatters(config.rules) }),
14
- [config, copy]
15
- );
16
- return /* @__PURE__ */ jsx(OvrConfigContext.Provider, { value, children });
17
- }
18
- function useCtx() {
19
- const ctx = React.useContext(OvrConfigContext);
20
- if (!ctx) {
21
- throw new Error(
22
- "[@gelabs/ovr-ui] hook used outside <OvrConfigProvider> \u2014 mount it in your root layout."
23
- );
24
- }
25
- return ctx;
26
- }
27
- function useOvrConfig() {
28
- return useCtx().config;
29
- }
30
- function useCopy() {
31
- return useCtx().copy;
32
- }
33
- function useFormatters() {
34
- return useCtx().formatters;
35
- }
36
-
37
- export { OvrConfigProvider, useCopy, useFormatters, useOvrConfig };
2
+ export { OvrConfigProvider, ThemeProvider, useCopy, useFormatters, useOvrConfig, useTheme } from './chunk-E2D7QT6N.js';
3
+ import './chunk-B634JHKZ.js';
@@ -1,6 +1,6 @@
1
1
  import { b as OvrConfig } from './schema-CdsFQxIg.js';
2
2
  import { a as Formatters } from './format-C7MSwUHK.js';
3
- import { D as Dictionary, C as CopyOverrides } from './types-DrrNO_Ak.js';
3
+ import { D as Dictionary, C as CopyOverrides } from './types-CtBC5-TW.js';
4
4
  import 'zod';
5
5
  import './types.js';
6
6
 
package/dist/ui-server.js CHANGED
@@ -1,4 +1,4 @@
1
- import { mergeCopy } from './chunk-JV7QQ22Q.js';
1
+ import { mergeCopy } from './chunk-5YYR37CF.js';
2
2
  import { createFormatters } from './chunk-B634JHKZ.js';
3
3
  import 'server-only';
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gelabs/ovr",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "The @gelabs/ovr SDK — one self-contained package over the OVR (Online Ordinance Violation Receipt) platform. A standalone per-LGU app installs ONLY this package and imports from @gelabs/ovr/{config,core,data,runtime,auth,ui,...}; the seven @gelabs/ovr-* implementation packages are bundled in at build time.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -98,6 +98,22 @@
98
98
  "types": "./dist/ui-components-ui/*.d.ts",
99
99
  "default": "./dist/ui-components-ui/*.js"
100
100
  },
101
+ "./ui/components/shared/*": {
102
+ "types": "./dist/ui-components-shared/*.d.ts",
103
+ "default": "./dist/ui-components-shared/*.js"
104
+ },
105
+ "./ui/components/admin/*": {
106
+ "types": "./dist/ui-components-admin/*.d.ts",
107
+ "default": "./dist/ui-components-admin/*.js"
108
+ },
109
+ "./ui/components/citizen/*": {
110
+ "types": "./dist/ui-components-citizen/*.d.ts",
111
+ "default": "./dist/ui-components-citizen/*.js"
112
+ },
113
+ "./offline": {
114
+ "types": "./dist/offline.d.ts",
115
+ "default": "./dist/offline.js"
116
+ },
101
117
  "./generated/client": "./dist/generated/client/index.js",
102
118
  "./prisma/schema.prisma": "./prisma/schema.prisma",
103
119
  "./styles.css": "./dist/styles.css",
@@ -117,10 +133,13 @@
117
133
  "@prisma/client": "^6.19.3",
118
134
  "class-variance-authority": "^0.7.1",
119
135
  "clsx": "^2.1.1",
136
+ "dexie": "^4.4.3",
137
+ "dexie-react-hooks": "^4.4.0",
120
138
  "ioredis": "^5.11.1",
121
139
  "lucide-react": "^1.17.0",
122
140
  "server-only": "^0.0.1",
123
141
  "shadcn": "^4.10.0",
142
+ "sonner": "^2.0.7",
124
143
  "tailwind-merge": "^3.6.0",
125
144
  "tw-animate-css": "^1.4.0",
126
145
  "zod": "^3"
@@ -139,13 +158,14 @@
139
158
  "react-dom": "19.2.4",
140
159
  "tsup": "^8.4.0",
141
160
  "typescript": "^5",
142
- "@gelabs/ovr-config": "0.0.0",
143
161
  "@gelabs/ovr-types": "0.0.0",
144
- "@gelabs/ovr-runtime": "0.0.0",
162
+ "@gelabs/ovr-config": "0.0.0",
145
163
  "@gelabs/ovr-data": "0.0.0",
146
164
  "@gelabs/ovr-core": "0.0.0",
147
165
  "@gelabs/ovr-auth": "0.0.0",
148
- "@gelabs/ovr-ui": "0.0.0"
166
+ "@gelabs/ovr-ui": "0.0.0",
167
+ "@gelabs/ovr-offline": "0.0.0",
168
+ "@gelabs/ovr-runtime": "0.0.0"
149
169
  },
150
170
  "scripts": {
151
171
  "build": "tsup && node scripts/copy-assets.mjs",
@@ -0,0 +1,142 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "ViolationCategory" AS ENUM ('TRAFFIC', 'ORDINANCE');
3
+
4
+ -- CreateEnum
5
+ CREATE TYPE "PaymentMethod" AS ENUM ('GCASH', 'MAYA', 'LANDBANK', 'OVER_THE_COUNTER');
6
+
7
+ -- CreateEnum
8
+ CREATE TYPE "PaymentStatus" AS ENUM ('UNPAID', 'PAID', 'CONTESTED');
9
+
10
+ -- CreateEnum
11
+ CREATE TYPE "UserRole" AS ENUM ('ENFORCER', 'ADMIN');
12
+
13
+ -- CreateTable
14
+ CREATE TABLE "Officer" (
15
+ "id" TEXT NOT NULL,
16
+ "name" TEXT NOT NULL,
17
+ "badgeNo" TEXT,
18
+ "office" TEXT NOT NULL,
19
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
20
+ "updatedAt" TIMESTAMP(3) NOT NULL,
21
+
22
+ CONSTRAINT "Officer_pkey" PRIMARY KEY ("id")
23
+ );
24
+
25
+ -- CreateTable
26
+ CREATE TABLE "ViolationCatalog" (
27
+ "code" TEXT NOT NULL,
28
+ "title" TEXT NOT NULL,
29
+ "category" "ViolationCategory" NOT NULL,
30
+ "basicFine" DECIMAL(12,2) NOT NULL,
31
+ "legalText" TEXT,
32
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
33
+
34
+ CONSTRAINT "ViolationCatalog_pkey" PRIMARY KEY ("code")
35
+ );
36
+
37
+ -- CreateTable
38
+ CREATE TABLE "Ticket" (
39
+ "ovrTicketNo" TEXT NOT NULL,
40
+ "orderOfPaymentNo" TEXT NOT NULL,
41
+ "billNo" TEXT NOT NULL,
42
+ "violatorFirstName" TEXT NOT NULL,
43
+ "violatorMiddleName" TEXT,
44
+ "violatorLastName" TEXT NOT NULL,
45
+ "violatorAddress" TEXT NOT NULL,
46
+ "violatorLicenseNumber" TEXT NOT NULL,
47
+ "violatorPlateNumber" TEXT,
48
+ "violatorContactNo" TEXT,
49
+ "apprehendedAt" TIMESTAMP(3) NOT NULL,
50
+ "placeOfViolation" TEXT,
51
+ "remarks" TEXT,
52
+ "officerId" TEXT NOT NULL,
53
+ "assessedAt" TIMESTAMP(3) NOT NULL,
54
+ "dueDate" TIMESTAMP(3) NOT NULL,
55
+ "basicFinesTotal" DECIMAL(12,2) NOT NULL,
56
+ "paymentStatus" "PaymentStatus" NOT NULL DEFAULT 'UNPAID',
57
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
58
+
59
+ CONSTRAINT "Ticket_pkey" PRIMARY KEY ("ovrTicketNo")
60
+ );
61
+
62
+ -- CreateTable
63
+ CREATE TABLE "TicketViolation" (
64
+ "id" TEXT NOT NULL,
65
+ "ticketOvrNo" TEXT NOT NULL,
66
+ "catalogCode" TEXT NOT NULL,
67
+ "title" TEXT NOT NULL,
68
+ "basicFine" DECIMAL(12,2) NOT NULL,
69
+ "details" TEXT,
70
+
71
+ CONSTRAINT "TicketViolation_pkey" PRIMARY KEY ("id")
72
+ );
73
+
74
+ -- CreateTable
75
+ CREATE TABLE "Payment" (
76
+ "id" TEXT NOT NULL,
77
+ "ticketOvrNo" TEXT NOT NULL,
78
+ "method" "PaymentMethod" NOT NULL,
79
+ "amount" DECIMAL(12,2) NOT NULL,
80
+ "referenceNo" TEXT NOT NULL,
81
+ "paidAt" TIMESTAMP(3) NOT NULL,
82
+
83
+ CONSTRAINT "Payment_pkey" PRIMARY KEY ("id")
84
+ );
85
+
86
+ -- CreateTable
87
+ CREATE TABLE "User" (
88
+ "id" TEXT NOT NULL,
89
+ "username" TEXT NOT NULL,
90
+ "passwordHash" TEXT NOT NULL,
91
+ "role" "UserRole" NOT NULL DEFAULT 'ENFORCER',
92
+ "active" BOOLEAN NOT NULL DEFAULT true,
93
+ "officerId" TEXT,
94
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
95
+
96
+ CONSTRAINT "User_pkey" PRIMARY KEY ("id")
97
+ );
98
+
99
+ -- CreateIndex
100
+ CREATE UNIQUE INDEX "Ticket_orderOfPaymentNo_key" ON "Ticket"("orderOfPaymentNo");
101
+
102
+ -- CreateIndex
103
+ CREATE UNIQUE INDEX "Ticket_billNo_key" ON "Ticket"("billNo");
104
+
105
+ -- CreateIndex
106
+ CREATE INDEX "Ticket_violatorLastName_idx" ON "Ticket"("violatorLastName");
107
+
108
+ -- CreateIndex
109
+ CREATE INDEX "Ticket_violatorPlateNumber_idx" ON "Ticket"("violatorPlateNumber");
110
+
111
+ -- CreateIndex
112
+ CREATE INDEX "Ticket_paymentStatus_idx" ON "Ticket"("paymentStatus");
113
+
114
+ -- CreateIndex
115
+ CREATE INDEX "Ticket_createdAt_idx" ON "Ticket"("createdAt");
116
+
117
+ -- CreateIndex
118
+ CREATE INDEX "TicketViolation_ticketOvrNo_idx" ON "TicketViolation"("ticketOvrNo");
119
+
120
+ -- CreateIndex
121
+ CREATE UNIQUE INDEX "Payment_ticketOvrNo_key" ON "Payment"("ticketOvrNo");
122
+
123
+ -- CreateIndex
124
+ CREATE UNIQUE INDEX "Payment_referenceNo_key" ON "Payment"("referenceNo");
125
+
126
+ -- CreateIndex
127
+ CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
128
+
129
+ -- CreateIndex
130
+ CREATE UNIQUE INDEX "User_officerId_key" ON "User"("officerId");
131
+
132
+ -- AddForeignKey
133
+ ALTER TABLE "Ticket" ADD CONSTRAINT "Ticket_officerId_fkey" FOREIGN KEY ("officerId") REFERENCES "Officer"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
134
+
135
+ -- AddForeignKey
136
+ ALTER TABLE "TicketViolation" ADD CONSTRAINT "TicketViolation_ticketOvrNo_fkey" FOREIGN KEY ("ticketOvrNo") REFERENCES "Ticket"("ovrTicketNo") ON DELETE CASCADE ON UPDATE CASCADE;
137
+
138
+ -- AddForeignKey
139
+ ALTER TABLE "Payment" ADD CONSTRAINT "Payment_ticketOvrNo_fkey" FOREIGN KEY ("ticketOvrNo") REFERENCES "Ticket"("ovrTicketNo") ON DELETE CASCADE ON UPDATE CASCADE;
140
+
141
+ -- AddForeignKey
142
+ ALTER TABLE "User" ADD CONSTRAINT "User_officerId_fkey" FOREIGN KEY ("officerId") REFERENCES "Officer"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,4 @@
1
+ -- Global ticket sequence used by createTicket (SELECT nextval('ovr_ticket_seq')
2
+ -- inside the insert transaction — atomic and collision-free under concurrency).
3
+ -- Starts at 4 because the three seed tickets occupy sequence values 1-3.
4
+ CREATE SEQUENCE IF NOT EXISTS ovr_ticket_seq START WITH 4 INCREMENT BY 1;
@@ -0,0 +1,26 @@
1
+ -- Split the single `violatorAddress` column into PH-standard address parts:
2
+ -- street (address line), barangay, city/municipality, province.
3
+
4
+ -- 1. Add the new columns as nullable so existing rows can be backfilled.
5
+ ALTER TABLE "Ticket" ADD COLUMN "violatorStreet" TEXT;
6
+ ALTER TABLE "Ticket" ADD COLUMN "violatorBarangay" TEXT;
7
+ ALTER TABLE "Ticket" ADD COLUMN "violatorCityMunicipality" TEXT;
8
+ ALTER TABLE "Ticket" ADD COLUMN "violatorProvince" TEXT;
9
+
10
+ -- 2. Backfill from the old comma-separated address
11
+ -- ("street, barangay, city, province"). Fall back to the LGU defaults so
12
+ -- sparsely-formatted legacy values still satisfy the NOT NULL constraints.
13
+ UPDATE "Ticket" SET
14
+ "violatorStreet" = COALESCE(NULLIF(TRIM(SPLIT_PART("violatorAddress", ',', 1)), ''), "violatorAddress"),
15
+ "violatorBarangay" = COALESCE(NULLIF(TRIM(SPLIT_PART("violatorAddress", ',', 2)), ''), '—'),
16
+ "violatorCityMunicipality" = COALESCE(NULLIF(TRIM(SPLIT_PART("violatorAddress", ',', 3)), ''), 'Iba'),
17
+ "violatorProvince" = COALESCE(NULLIF(TRIM(SPLIT_PART("violatorAddress", ',', 4)), ''), 'Zambales');
18
+
19
+ -- 3. Enforce NOT NULL now that every row has values.
20
+ ALTER TABLE "Ticket" ALTER COLUMN "violatorStreet" SET NOT NULL;
21
+ ALTER TABLE "Ticket" ALTER COLUMN "violatorBarangay" SET NOT NULL;
22
+ ALTER TABLE "Ticket" ALTER COLUMN "violatorCityMunicipality" SET NOT NULL;
23
+ ALTER TABLE "Ticket" ALTER COLUMN "violatorProvince" SET NOT NULL;
24
+
25
+ -- 4. Drop the old single column.
26
+ ALTER TABLE "Ticket" DROP COLUMN "violatorAddress";
@@ -0,0 +1,2 @@
1
+ -- Make Barangay optional: drop the NOT NULL constraint on violatorBarangay.
2
+ ALTER TABLE "Ticket" ALTER COLUMN "violatorBarangay" DROP NOT NULL;
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"