Full-stack application

CariPasal

An Indonesian legal article search and management system with an offline-first Flutter app, editorial dashboard, and Laravel backend.

Request demo accessLogin access is available on request.
Year2026
Services
  • Application engineering
  • Backend migration
  • Deployment and CI/CD
Technologies
  • Flutter
  • Dart
  • Laravel
  • PostgreSQL
  • Drift
  • SQLite
  • React
  • TypeScript

Problem and requirements

Legal article references need to be searchable and remain available when connectivity is unreliable. CariPasal separates reading from content administration: its Flutter app stores legal data locally, while an admin dashboard manages laws, articles, relationships, users, and audit records.

The product initially used Supabase Auth, RLS, RPCs, and Edge Functions. As deployment and backend control requirements changed, the system moved to Laravel and PostgreSQL without replacing the Flutter app, React dashboard, UUIDs, core schema, or offline workflow.

Application implementation

Flutter uses Drift and SQLite to store laws, articles, and relationships. After its first full sync, readers can search locally by article number, title, content, and keyword, open article details, move to previous or next articles, inspect relationships, save articles, and copy content to the clipboard.

Search normalises input such as Pasal 16A, then prioritises exact, prefix, and numeric article-number matches. The dashboard provides CRUD, trash and restore, bulk actions, Excel import, and OCR for photographed book pages. OCR preprocesses images in the browser, removes noise, recognises article and explanation structure, and gives administrators an editable draft before import.

Production architecture

The active runtime consists of a React dashboard and Flutter app communicating with a Laravel REST API. Laravel handles Sanctum authentication, role authorisation, CRUD, imports, audit records, password reset, and synchronisation. PostgreSQL preserves UUIDs, JSONB, relationship constraints, and a data structure close to the previous Supabase system.

Incremental sync requests changes since the last timestamp, applies a five-minute time overlap, upserts new or changed records, and propagates deleted or inactive record IDs to Drift. Docker Compose provides a local stack for the admin app, Flutter Web, Laravel, PostgreSQL, and Mailpit. The aaPanel deployment script runs migrations, caching, permission fixes, the admin build, PHP-FPM restart, Nginx reload, and a health check.

Security and operations

Admin routes use Sanctum and role middleware; admin management is restricted to super admins. Mobile accounts have an active period and device binding with a maximum of three devices. Tokens can be revoked on logout or password reset, while mobile sessions store sensitive values through FlutterSecureStorage and check expiry both offline and online.

Audit logs store the actor, action, table, record, JSON changes, request metadata, IP, user agent, and timestamp. Flutter unit tests cover models, search, archive, queries, sync state, progress, and error classification. Admin and Flutter Web builds are verified through CI. Backend integration tests, rate limiting, server-side upload limits, and chunked full sync remain areas for further hardening.