feat: implement PouchDB storage layer with CRUD operations and add showcase UI component

This commit is contained in:
Firman Ramdhani
2026-05-29 15:35:14 +07:00
parent 86c02e7111
commit 6712558eaf
15 changed files with 1820 additions and 309 deletions
+57
View File
@@ -0,0 +1,57 @@
/**
* Multi-Database PouchDB Configuration for apps/web.
*
* This module demonstrates the IoC pattern: the consuming app decides
* which databases to create and where they sync to. The core engine
* (`PouchDatabaseManager`) has zero knowledge of business domains.
*/
import { PouchDatabaseManager } from '@repo/core-storage';
import { ENV } from '../../environment/env';
import type { Item, POSConfiguration } from './types';
// ─── Manager Singleton ──────────────────────────────────────────
export const dbManager = new PouchDatabaseManager();
// ─── Helper: Build Secure Remote URL ────────────────────────────
function buildRemoteUrl(dbName: string): string | undefined {
const { COUCHDB_BASE_URL, COUCHDB_USERNAME, COUCHDB_PASSWORD } = ENV;
if (!COUCHDB_BASE_URL || !COUCHDB_USERNAME || !COUCHDB_PASSWORD) {
console.warn(`[DB Config] CouchDB credentials missing — "${dbName}" will run in offline-only mode.`);
return undefined;
}
// 1. Tambahkan http:// secara otomatis jika DevOps hanya mengisi IP Address di .env
const safeBaseUrl = COUCHDB_BASE_URL.startsWith('http')
? COUCHDB_BASE_URL
: `http://${COUCHDB_BASE_URL}`;
try {
// 2. Gunakan URL parser yang aman dari karakter aneh pada password
const url = new URL(safeBaseUrl);
url.username = encodeURIComponent(COUCHDB_USERNAME);
url.password = encodeURIComponent(COUCHDB_PASSWORD);
url.pathname = `/${dbName}`;
return url.toString();
} catch (error) {
console.error(`[DB Config] Invalid URL format for CouchDB:`, safeBaseUrl);
return undefined;
}
}
// ─── Register Application Databases ─────────────────────────────
/** POS Configuration database — stores device settings, theme, etc. */
export const posConfigDB = dbManager.register<POSConfiguration>({
localName: 'pos_configuration',
remoteUrl: buildRemoteUrl('pos_configuration'),
});
/** Items database — products available for sale in POS. */
export const itemDB = dbManager.register<Item>({
localName: 'item',
remoteUrl: buildRemoteUrl('item'),
});
+47
View File
@@ -0,0 +1,47 @@
/**
* Enterprise ERP Data Domain Models
* These types reflect the actual schema of the underlying CouchDB instances.
*/
export interface ItemRate {
season_period?: string | null;
price: string | number;
}
export interface ItemCategory {
_id?: string;
name?: string;
[key: string]: any;
}
/**
* Represents a sellable product or service.
*/
export interface Item {
_id: string;
_rev?: string;
name: string;
base_price: string | number;
item_type: string;
usage_type?: string;
item_category?: ItemCategory[] | ItemCategory | string;
item_rates?: ItemRate[];
// Allow for other ERP-specific fields
[key: string]: any;
}
/**
* Represents the configuration and assigned data for a specific Point of Sale terminal.
*/
export interface POSConfiguration {
_id: string;
_rev?: string;
pos_number: string;
pos_name: string;
items: Item[];
payment_methods?: any[];
// Allow for other ERP-specific fields
[key: string]: any;
}