Skip to main content

Architecture

The Mini POS System uses IndexedDB for client-side data persistence. The database provides a simple, promise-based API for managing products and sales records.

Database Configuration

const DB_NAME = 'pos-db';
const DB_VER = 1;

Schema

The database contains two object stores:

Products Store

  • Name: products
  • Key Path: id (auto-increment)
  • Indexes: None
  • Structure:
    {
      id: number,        // Auto-generated
      name: string,      // Product name
      price: number      // Product price
    }
    

Sales Store

  • Name: sales
  • Key Path: id (auto-increment)
  • Indexes: date (for range queries)
  • Structure:
    {
      id: number,        // Auto-generated
      date: string,      // ISO 8601 date string
      items: Array,      // Array of sale items
      total: number      // Total sale amount
    }
    

Core Functions

openDB()

Opens a connection to the IndexedDB database. Creates object stores if they don’t exist.
Promise<IDBDatabase>
Promise
Resolves with the database connection
Implementation:
js/db.js
function openDB() {
  return new Promise((resolve, reject) => {
    const req = indexedDB.open(DB_NAME, DB_VER);
    req.onupgradeneeded = () => {
      const db = req.result;
      if (!db.objectStoreNames.contains('products')) {
        db.createObjectStore('products', { keyPath: 'id', autoIncrement: true });
      }
      if (!db.objectStoreNames.contains('sales')) {
        const store = db.createObjectStore('sales', { keyPath: 'id', autoIncrement: true });
        store.createIndex('date', 'date');
      }
    };
    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(req.error);
  });
}
Error Handling:
  • Rejects if the database cannot be opened
  • Rejects if there are permission issues
  • Rejects if IndexedDB is not supported

tx()

Helper function for executing transactions. Simplifies transaction management by handling connection and cleanup.
store
string
required
Name of the object store (‘products’ or ‘sales’)
mode
string
required
Transaction mode: ‘readonly’ or ‘readwrite’
fn
function
required
Callback function that receives the object store and performs operations
Promise<any>
Promise
Resolves with the result of the transaction
Implementation:
js/db.js
async function tx(store, mode, fn) {
  const db = await openDB();
  return new Promise((resolve, reject) => {
    const t = db.transaction(store, mode);
    const s = t.objectStore(store);
    const out = fn(s);
    t.oncomplete = () => resolve(out?.result ?? out);
    t.onerror = () => reject(t.error);
  });
}
Error Handling:
  • Rejects if the database connection fails
  • Rejects if the transaction fails
  • Rejects if the object store doesn’t exist

Connection Management

The database connection is managed automatically:
  1. openDB() is called for each transaction
  2. IndexedDB returns cached connections when available
  3. Connections are automatically closed after transactions complete
  4. Schema upgrades happen automatically on version changes

Usage Pattern

All database operations follow this pattern:
// 1. Import the function
import { getProducts } from './js/db.js';

// 2. Call the async function
const products = await getProducts();

// 3. Handle errors with try/catch
try {
  const products = await getProducts();
  console.log(products);
} catch (error) {
  console.error('Database error:', error);
}

Build docs developers (and LLMs) love