NastyCookie NastyCookie ERP

Comprehensive user guide for the NastyCookie manufacturing and inventory management platform.

v2.0 May 2026 6 Modules Role-Based Access

System Changes & Release Notes

 Halal Certification Expiry Alerts — Inventory 30 Jun 2026

The Inventory list in the Warehouse module now automatically surfaces SKUs whose halal certification is expiring soon, so compliance renewals are never missed.

  • Auto-sort to top — SKUs with a halal cert expiry within 90 days (or already expired) are floated above all other non-critical inventory rows
  • Earliest expiry first — within the halal-alert group, the soonest-to-expire SKU appears at the very top
  • Yellow row highlight — amber background and left border distinguish halal-alert rows from normal (white) and below-MRP (red) rows
  • Inline badge — each alerting row shows a "Halal Exp: DD MMM YYYY" badge under the product name; already-expired certs show "Halal EXPIRED"
  • MRP priority preserved — Below-MRP rows remain at the very top in red; halal alerts slot in immediately below them
Setup required: Halal expiry alerting only activates for SKUs that have the Halal Cert Expiry date filled in the SKU Master. SKUs without this field are unaffected.
 Multi-Currency Support 28 Jun 2026

Purchase Orders and Sales Orders can now be transacted in currencies other than MYR. All financial data is stored in MYR internally; currency is a display and entry layer only.

  • Currency selector on PO create form — choose MYR, SGD, or any configured currency
  • Auto-conversion — prices entered in foreign currency are multiplied by the exchange rate and stored in MYR
  • Rate locked at creation — the rate used is stored with the document; future rate changes do not alter historical records
  • Visual highlight — non-MYR POs show an amber SGD badge in lists and a "Transacted in SGD @ 3.14 MYR" banner in the detail view
  • Dual amounts — detail view shows both foreign and MYR totals (e.g. SGD 100.00 / MYR 314.00)
  • GRN & auto-invoices — inherit currency from the parent PO; credit notes auto-generated on shortfall also carry the correct currency
  • Amend flow — when amending a foreign-currency PO, prices are displayed in the original currency (back-converted from stored MYR)
  • Settings — manage currencies and exchange rates in Tax & Finance Settings → Currencies section
No impact on existing data. All historical POs and SOs default to MYR (rate 1:1) and display exactly as before.

Future updates will appear here in reverse-chronological order.

System Overview

NastyCookie ERP is an integrated enterprise resource planning system designed for cookie and food manufacturing. It covers the full business cycle — from purchasing raw materials through production to delivering finished goods to customers — with real-time inventory tracking, financial reconciliation, and team-wide audit trails.

Warehouse

Inventory, SKUs, picking, locations

Inbound

Purchase orders, suppliers, GRN

Outbound

Sales orders, dispatch, invoices

Production

Scheduling, batches, QC

Finance

Reconciliation, invoices

Management

Users, settings, notifications

Access via Tailscale: Remote users connect to http://100.86.94.99:8888 after joining the Tailscale network. The host machine must be running both the API server (port 3000) and UI server (port 8888).

Logging In

  1. 1Open the ERP URL in your browser (e.g. http://100.86.94.99:8888 on the office network).
  2. 2Enter your email address and password. First-time users enter the temporary password provided by the administrator.
  3. 3If this is your first login, you will be prompted to set a new password before continuing.
  4. 4After login you land on the Dashboard which shows KPI summaries for all modules you have access to.

Forgot your password? Contact your system administrator. They can reset it and the new temporary password will be emailed to you automatically.

Logging Out

Click your name in the top-right header → Logout. Or navigate to Management → User Management and click the Logout button in the session bar. Your session is cleared immediately.

Roles & Permissions

Every user is assigned one or more roles. Each role grants a set of permissions that control exactly which pages and actions are available.

RoleTypical UsersKey Access
super_adminIT / OwnerUnrestricted access to everything — protected, cannot be edited or deleted
erp_adminERP ManagerFull system across all modules — protected
management_adminOperations HeadUser management, roles, settings, audit logs
warehouse_managerWarehouse ManagerFull warehouse, receiving, dispatch oversight
warehouse_operatorWarehouse TeamInventory, picking, stock movement
inbound_managerPurchasingPOs, GRNs, supplier approvals, QC
receiving_clerkReceiving StaffGoods receipt operations, view POs
outbound_managerSales / DispatchSales orders, dispatch, customer invoices
finance_managerFinance TeamFinance overview, bank reconciliation, invoices
executive_viewerObserversDashboard and overview pages only, read-only

Administrators can create custom roles with any combination of permissions. Go to Management → User Management → Roles tab → New Role. Requires management.users.assign_roles.

Permission Naming Convention

Permissions follow the pattern module.resource.action. For example:

  • warehouse.inventory.read — view inventory levels
  • outbound.sales_orders.approve — approve a sales order
  • management.users.create — create new user accounts
  • finance.reconciliation.write — edit bank reconciliation

Finance Permission Catalogue

PermissionWhat it grants
finance.overview.readView Finance Overview page and KPI summary
finance.reconciliation.readView bank reconciliation periods and transaction details
finance.reconciliation.writeCreate/edit periods, upload statements, reconcile categories, manage parked entries
finance.reconciliation.adminLock (complete) periods, delete periods, export journal entries
finance.invoices.readView supplier and customer invoices in the Finance module

User Management Permission Catalogue

PermissionWhat it grants
management.users.readView the User Management page and user list
management.users.createCreate new user accounts (shows Add User button)
management.users.update_profileEdit user name and department
management.users.reset_passwordGenerate a new temporary password for a user
management.users.lock_unlockLock or unlock user accounts
management.users.assign_rolesAssign roles to users and create/edit roles in the Roles tab
management.users.activate_deactivateChange account status between Active and Inactive

Warehouse Module

Manages all physical stock — what you have, where it is, and when to reorder. The warehouse is the source of truth for inventory across all other modules.

Inventory

Displays all SKUs with on-hand, allocated, and available quantities grouped by product. Drill down to see per-location breakdowns including batch and lot numbers.

ColumnMeaning
On HandTotal physical stock in the warehouse
AllocatedReserved for approved sales orders (not yet shipped)
AvailableOn Hand minus Allocated — what you can actually sell

Row Colour Coding & Sort Priority

Inventory rows are automatically sorted and colour-coded by urgency. Higher-priority rows always appear above lower-priority ones.

PriorityConditionRow colourLeft border
1 — HighestAvailable stock is below the SKU's Minimum Reorder PointLight redRed
2Halal cert expiry is within 90 days or already expired — sorted earliest-first within this groupAmber / YellowAmber
3 — NormalNo alert conditions — standard inventory rowsWhite / light greyNone

Halal badge: Alerting rows show a "Halal Exp: DD MMM YYYY" tag under the product name. Rows whose cert has already lapsed show "Halal EXPIRED" in the same amber badge. A SKU only enters this group if its Halal Cert Expiry field is populated in the SKU Master.

SKU Master

The product catalogue. Every item in the warehouse must have an SKU record. SKU codes are auto-generated by category prefix:

  • RM-xxxx — Raw Materials
  • FG-xxxx — Finished Goods
  • PK-xxxx — Packaging
  • WP-xxxx — Work In Progress

Each SKU stores minimum stock, reorder point, cost per unit, selling price, storage type (ambient/refrigerated/frozen), and halal certification expiry.

Picking Lists

Picking lists are auto-generated when a Sales Order is approved. They guide warehouse staff to pick the right quantities from the right locations.

SO Approved Picking List Created Assign Picker Pick Items Mark Complete Staged for Dispatch

Locations

Defines warehouse bins and racks. Each location belongs to a zone (A, B, C, FG, Cold) and has a capacity in kg. Stock is tracked per-location for precise inventory control.

Stock Count

Conduct a physical count of actual stock. After counting, the system shows variances between system quantity and physical count. A manager must approve variances before they are applied.

  1. 1Click New Stock Count and select the scope (full warehouse or specific zone).
  2. 2Warehouse staff physically counts items and enters quantities.
  3. 3System highlights discrepancies in red.
  4. 4Manager reviews and approves — system adjusts inventory accordingly.

Inbound Module

Manages everything coming INTO the company — purchase orders to suppliers, receiving goods, and quality checks.

Purchase Orders (PO)

Raise purchase orders to buy materials from suppliers. POs go through an approval workflow before being sent.

Draft Submitted Approved Sent Received

Creating a PO

  1. 1Go to Inbound → Purchase Orders → New PO.
  2. 2Select supplier and expected delivery date.
  3. 3Add line items (SKU, quantity, unit price).
  4. 4Save as Draft or Submit for approval.
  5. 5A manager approves and marks as Sent to supplier.

Multi-Currency POs

When creating a PO, select the supplier's billing currency from the Currency dropdown. The system will:

  1. Show the exchange rate (e.g. 1 SGD = MYR 3.14)
  2. Accept item prices in the selected currency
  3. Convert and store all amounts in MYR automatically
  4. Display an amber SGD badge on non-MYR rows in the PO list
  5. Show both currency amounts in the PO detail view

Note: The exchange rate is locked at the time of PO creation. To update rates, go to Settings → Tax & Finance → Currencies.

Goods Receiving (GRN)

When goods arrive, raise a Goods Receipt Note (GRN) against the approved PO. Received items are added to warehouse stock automatically.

  1. 1Go to Warehouse → Goods Receiving and find the corresponding PO.
  2. 2Enter received quantities (may differ from ordered).
  3. 3Enter batch numbers and expiry dates for traceable items.
  4. 4Post the GRN — stock levels update immediately.

QC Hold

Items that fail inspection at goods receiving are placed on QC Hold. They cannot be used in production or sold until released or rejected.

  • Release — item passes QC, returned to available stock
  • Reject — item fails QC, triggers supplier return process

Outbound Module

Manages everything going OUT to customers — quotations, sales orders, picking, dispatch, and invoicing.

Quotations

Send price quotes to customers before committing to a sale. Quotations can be converted directly into Sales Orders when accepted.

Draft Sent Accepted → SO

Sales Orders (SO)

Confirmed orders from customers. Approving an SO triggers automatic stock reservation (FIFO allocation) and picking list generation.

Draft Approved Picking Staged Delivered

Secondary status badges in the SO list show both the order status AND the pick status (e.g. Picking In Progress).

Dispatch

The dispatch page uses a two-panel layout:

  • Left panel — Staged Queue: SOs where picking is complete and goods are ready to ship. Tick one or more SOs to include in a dispatch run.
  • Right panel — Dispatch Plans: Created dispatch plans showing driver, vehicle, and linked SOs. Click Mark All Delivered to complete a run.
  1. 1Select one or more staged orders on the left.
  2. 2Click Create Dispatch Plan, enter driver and vehicle details.
  3. 3When goods are delivered, click Mark All Delivered — all linked SOs advance to Delivered and invoices are created.

Customer Returns

Log returned goods from customers. Returns are reviewed and either restocked (good condition) or written off (damaged). Credit notes are generated automatically.

Production Module

The Production module is the manufacturing core of NastyCookie ERP. It orchestrates the full production lifecycle — from scheduling baking jobs and managing room and manpower capacity, through ingredient fulfilment and real-time batch tracking, to quality control, finished goods handover, and cost analysis. It integrates tightly with Warehouse (ingredient supply and finished goods receipt), Inbound (raw material availability), Outbound (finished goods for sale), and Finance (cost of goods sold).

Sub-modules: Production Overview  ·  Room Templates  ·  Job Templates  ·  Manpower Templates  ·  Production Users & Skills  ·  Production Scheduler  ·  Schedule Views  ·  Ingredient Requests  ·  Production Inventory  ·  Production QC  ·  Finished Goods  ·  Production In/Out  ·  Costing

How Production Interacts With Other Modules

ModuleDirectionWhat Flows
Inbound→ ProductionReceived raw materials are added to Warehouse stock via GRN. Production then requests them via Ingredient Requests.
Warehouse↔ ProductionIn: Ingredients pulled from Warehouse into Production Inventory via approved Ingredient Requests.
Out: QC-passed Finished Goods pushed back to Warehouse via Production In/Out.
OutboundProduction →Once Finished Goods are received by the Warehouse, they become available stock for Sales Orders and Dispatch.
FinanceProduction →Costing module produces per-batch cost (raw materials + labour) which informs COGS reporting and margin analysis.
Management→ ProductionRecipes (BOMs) are maintained under Management → Recipes (Restricted). Only approved recipe versions can be used in Job Templates and the Scheduler.

Production Overview

The Production Overview is the daily command centre. It shows live KPI cards and four real-time activity panels that surface items requiring immediate attention.

KPI CardWhat It Shows
In ProgressNumber of jobs currently running on the production floor
Awaiting QCCompleted batches that have not yet been quality-checked
Completed TodayBatches that have passed QC and closed out today

Activity Panels

  • Active Jobs — running scheduler jobs with quick link to Scheduler.
  • Awaiting QC — batches pending quality inspection with quick link to Production QC.
  • Ingredient Requests — pending or partially fulfilled ingredient requests with quick link to that page.
  • Finished Goods Pending — QC-passed batches not yet transferred to Warehouse with quick link to Finished Goods.

Room Templates

Rooms are the physical production spaces where work happens. Each Room Template defines a space that the Scheduler can book. Rooms must be configured before any jobs can be scheduled.

FieldDescription
Room CodeUnique identifier, e.g. MIX-01, BAKE-02
Room NameDescriptive label shown in the Scheduler timeline
TypeMixing Shaping Baking Cooling Packing
WorkspacePhysical area or bench description (informational)
CapacityMaximum batch volume this room can handle simultaneously
StatusActive rooms appear in the Scheduler; Inactive rooms are hidden

Room types map directly to production stages. A typical cookie run requires a Mixing room, then a Shaping room, then a Baking room, then a Cooling room, then a Packing room — modelled as separate processes in a Job Template, each booked against the relevant room type.

Manpower Templates

Manpower Templates define categories of labour used in production (e.g. Baker, Mixer Operator, Packer). They are not individual people — individual workers are registered separately in Production Users.

FieldDescription
CodeShort identifier, e.g. BAKER, PACKER, QC-OFFICER
NameRole name displayed on schedule cards and costing reports
DescriptionResponsibilities and scope
Hourly CostLabour rate per hour — fed into the Costing module to calculate total job labour expense
StatusActive / Inactive

Costing link: Hourly Cost × actual hours worked per manpower type (summed across all job processes) = total labour cost for a batch. Keep hourly costs current to ensure accurate batch costing.

Job Templates

A Job Template is a reusable production blueprint. It links an approved recipe to an ordered sequence of processes, each assigned to a room type and manpower type. The Scheduler uses Job Templates to pre-fill all job settings when a new run is inserted.

FieldDescription
Template CodeUnique identifier, e.g. JT-CHOC-001
NameHuman-readable label, e.g. "Chocolate Chip Cookie — Standard Run"
RecipeLinks to an approved recipe from Management → Recipes. Dictates which ingredients are consumed and in what quantities per batch.
BatchesDefault batch count (overridable at scheduling time)
DurationTotal expected run time in minutes (sum of all process durations)
ProcessesOrdered list of sub-steps (e.g. Mix → Shape → Bake → Cool → Pack), each specifying room type, manpower type, and duration
StatusActive / Inactive

Recipe must be approved before a Job Template can reference it. Unapproved recipe versions are locked for production use. Approve recipes under Management → Recipes (Restricted) — requires management.recipes.update.

Production Users & Skills

Register individual production workers and assign them skills. The Scheduler uses skills to validate that workers assigned to a process are qualified for it.

Production Users (left panel)

  • Each worker has a name, employee ID, and one or more assigned skills.
  • Filter workers by skill using the dropdown in the search bar to quickly identify qualified staff for a given process.
  • Inactive workers are hidden from the Scheduler's manpower assignment panel.

Skills (right panel)

  • Skills are defined here (e.g. "Chocolate Mixing", "Oven Operation", "Packaging Machine").
  • Click a skill to toggle assignment for the selected worker. Skills can also be assigned by drag-and-drop onto a worker card.
  • Skills are immediately reflected in the Scheduler without a page reload.

Best practice: Register all production staff and assign their skills before building Job Templates. This ensures the Scheduler can immediately suggest qualified workers when a job is inserted.

Production Scheduler

The Scheduler is the operational heart of the Production module. It presents a drag-and-drop weekly timeline where jobs are placed into time slots against rooms and manpower. Each week is saved as a named schedule and persists until overwritten.

Layout

ElementDescription
Job Queue (left panel)Jobs inserted but not yet placed on the timeline. Collapsible. Click Insert Job to add a new job from a template.
Timeline (main panel)Weekly grid. Rows = rooms; columns = time slots. Drag jobs from the queue onto the grid to schedule them.
Week NavigatorShows the active week. Use chevrons to browse; New Week starts a fresh schedule for the coming week.
Zoom ControlsSwitch between 15 min, 30 min, and 1 hr column increments to suit the density of the schedule.
Delivery Plan ReferenceIf a delivery plan exists for the current week it appears at the bottom as a read-only strip — use it to align production timing with dispatch deadlines.

Scheduling a Job — Step by Step

  1. 1Click Insert Job in the Job Queue panel. Select a Job Template and set the number of batches for this run.
  2. 2The job card appears in the queue showing expected duration and ingredient summary drawn from the template's linked recipe.
  3. 3Drag the job card onto the timeline at the desired start time and room row.
  4. 4Click the placed job block to open its detail panel. Assign workers whose skills match each process requirement.
  5. 5Click Save Schedule. The week's schedule is persisted and immediately visible to all production staff.

Job Lifecycle

Queued Scheduled In Progress Awaiting QC QC Passed Completed

Time Settings

Click the Time Settings (clock) button to configure the factory's working-hours window. Default: 08:00–17:30. The timeline enforces this window and will visually flag jobs placed outside it.

Undo

The Undo button reverses the last drag action on the timeline. It is only active before saving — it cannot undo a saved schedule.

Stock is not auto-blocked: The Scheduler does not prevent scheduling if ingredients are insufficient. The planner must manually verify Production Inventory → Live Stock (or confirm a pending Ingredient Request) before placing a job.

Schedule Views

Schedule Views are read-only visualisations of the current week's saved schedule in three formats. Use these for shift briefings, management reporting, and sharing with staff who do not need edit access to the Scheduler.

ViewLayoutBest Used For
Room ViewTimetable grid — rows = rooms, columns = time slots. Shows which jobs occupy which rooms at every moment.Shift planning, room utilisation, identifying gaps
GanttClassic Gantt chart — jobs as horizontal duration bars on a time axis.Timeline overview, management reporting, deadline tracking
User ViewSchedule grouped by worker — shows each person's assignments and time blocks.Individual staff briefings, overtime checks, manpower conflicts

Schedule Views always reflect the last saved state of the scheduler. Unsaved changes in the Scheduler will not appear here.

Ingredient Requests

Ingredient Requests are the formal mechanism by which Production requisitions raw materials from the Warehouse. Stock does not move until the request is approved and fulfilled by the Warehouse team.

Production raises Request Warehouse reviews & approves Warehouse picks & delivers Production confirms receipt (In/Out → In) Stock deducted from Warehouse; added to Production Inventory

Key Rules

  • Each request is linked to a scheduled job so ingredient consumption is traceable per batch.
  • Partial fulfilment is supported — Warehouse can deliver part of the request now and mark the remainder pending.
  • Raw materials on QC Hold in the Warehouse cannot be transferred to Production until QC releases them.
  • The Production Overview's Ingredient Requests panel shows all pending requests in real time.

Cross-module: Ingredient Requests appear in both the Production module (raised here) and the Warehouse module (approved and fulfilled there). Both sides see live status updates.

Production Inventory

Production maintains its own inventory ledger — separate from the main Warehouse — covering raw materials, packaging, and finished goods physically held in the production facility. It has three tabs:

Live Stock Tab

ColumnMeaning
ExpectingQuantity from approved Ingredient Requests not yet physically received into the production space
ExistingQuantity physically on hand in the production facility right now
AvailableExisting minus quantities reserved for currently scheduled jobs

Filter by category (Raw Material / Finished Good / Packaging) or search by SKU / product name.

Inventory Count Tab

Conduct a physical count of production stock. Staff enters actual quantities; the system calculates variance against the system figure. A variance summary appears in the header before submission.

  1. 1Enter actual physical counts in the Actual Count column for each SKU line.
  2. 2System calculates variance (actual − system). Negative = missing stock; positive = surplus.
  3. 3Add notes for any lines with significant variance.
  4. 4Click Submit Count to commit adjustments. Production Inventory levels update immediately.

Count History Tab

Full audit trail of all past production inventory counts: Count #, Date, Items counted, Net Variance, Status, Type, and who submitted it.

The Reset Inventory button (admin-only, hidden by default) wipes all production inventory records. Use only during initial system setup or at the start of a new accounting period — this action is irreversible.

Production QC

After a batch finishes production it moves to QC before the output can enter Finished Goods. This gate prevents substandard product from reaching the Warehouse or customers.

QC Statuses

StatusMeaningNext Action
In ProgressBatch still running — QC not yet applicableWait for batch completion
Awaiting QCBatch finished; pending quality inspectionQC officer opens the batch and records checks
QC PassedAll checks passed; approved for Finished GoodsBatch entry created in Finished Goods; costing calculated
QC FailedCritical failure; batch rejectedBatch written off or scrapped; non-conformance note recorded
Rework RequiredMinor issues; batch returned to production for correctionRework job inserted in Scheduler; batch re-QC'd after completion

QC Table Columns

Batch #, Recipe, Planned Qty, Actual Qty, Batch Status, QC Status, Actions. The Planned vs Actual Qty gap is the primary quality signal — a large discrepancy indicates waste, a recipe deviation, or a weighing error that should be investigated before passing.

Cross-module: QC Passed batches automatically create a Finished Goods record. They do not immediately appear in Warehouse inventory — the formal handover happens in Production In/Out → Out.

Finished Goods

Finished Goods is a holding ledger for QC-passed batches that are ready to be transferred to the Warehouse but have not yet been handed over. Think of it as the production side of the transfer waiting room.

  • Each entry shows recipe, batch number, quantity produced, and production date.
  • Items here do not appear in Warehouse inventory and cannot be allocated to Sales Orders.
  • To move stock to the Warehouse, use Production In/Out → Out.
  • The Production Overview's "Finished Goods Pending" panel surfaces unshipped items — monitor this daily to prevent expiry of perishable products.

Perishable risk: Cookies have short shelf lives. Finished Goods that are not transferred promptly may approach their best-before date before reaching the customer. The production manager should target same-day or next-day transfer for fresh-baked goods.

Production In / Out

Production In/Out is the transfer gateway between the Production and Warehouse modules. It handles both directions of stock movement and provides a full audit trail for every transfer.

In — Inbound Receipts

Records raw materials physically arriving into the production facility from the Warehouse (fulfilling an approved Ingredient Request).

  1. 1Warehouse dispatches ingredients against an approved Ingredient Request; status moves to "Dispatched".
  2. 2Production sees the pending receipt here under the Pending Receipt filter.
  3. 3Production opens the receipt modal, verifies expected vs actually received quantities per ingredient line, and adds notes for any discrepancy.
  4. 4Production confirms receipt — Production Inventory is updated (ingredients move from "Expecting" to "Existing").

Out — Transfer to Warehouse

Records Finished Goods being handed from Production to the Warehouse. This is the exact moment products enter Warehouse inventory and become available for Sales Orders.

Pending Dispatch Dispatched — Awaiting Warehouse Received by Warehouse
  1. 1Production initiates a transfer for one or more Finished Goods batches (from the Out tab).
  2. 2Status changes to Dispatched — Awaiting Warehouse; Warehouse is notified.
  3. 3Warehouse receives goods physically, confirms quantities in their module, and marks Received.
  4. 4Warehouse inventory is updated — Finished Goods SKU is now available for Sales Orders and Dispatch.

Cross-module: The "Received by Warehouse" confirmation step is the precise handover point. Until this step, the product is Production's responsibility and cannot be sold. After it, the product is under Warehouse control and can be allocated to Outbound orders.

Costing

The Costing sub-module calculates the total cost of each production batch. Results feed into Finance for COGS reporting and can be compared against selling prices (from the SKU Master) for margin analysis.

Cost ComponentSource DataCalculation
Raw Material CostRecipe BOM quantities + SKU Master unit costQty consumed per ingredient × unit cost, summed across all BOM lines
Labour CostManpower Template hourly rates + actual hours per processHours worked × hourly cost per manpower type, summed across all job processes
Total Batch CostRaw Material Cost + Labour Cost
Cost Per UnitQC Actual Qty outputTotal Batch Cost ÷ Actual Qty produced (from QC record)

Cross-module: Cost Per Unit flows to Finance for COGS calculations and can be benchmarked against the selling price in the SKU Master (set in the Warehouse module) to produce per-SKU margin reports.

Production Permissions

PermissionWhat It Grants
production.overview.readView the Production Overview KPI and activity panels
production.scheduler.readView the Scheduler timeline (read-only)
production.scheduler.writeCreate, modify, and save schedules; insert and move jobs on the timeline
production.templates.readView Room, Job, and Manpower templates
production.templates.writeCreate and edit Room, Job, and Manpower templates
production.users.readView Production Users list and skill assignments
production.users.writeAdd/edit production workers and assign skills
production.qc.readView QC records, batch statuses, and planned vs actual quantities
production.qc.writeRecord QC results; set batches to Pass, Fail, or Rework
production.inventory.readView Production Inventory (live stock, count history)
production.inventory.writeSubmit inventory count adjustments
production.inventory.adminReset production inventory — destructive, admins only
production.inout.readView Production In/Out transfer records and statuses
production.inout.writeConfirm inbound ingredient receipts; initiate outbound finished goods transfers
production.costing.readView batch cost breakdowns and per-unit cost reports
management.recipes.readView recipes (BOMs) — required for Job Template creation
management.recipes.updateEdit and approve recipe versions — required to unlock recipes for production use

End-to-End Production Workflow

Complete sequence from initial setup through to finished product available for sale.

  1. 1One-time setup: Configure Room Templates (production spaces), Manpower Templates (labour categories), register Production Users and assign their skills.
  2. 2Recipe approved: Management approves the recipe version under Management → Recipes (Restricted). An unapproved recipe blocks Job Template creation.
  3. 3Job Template created: Link the approved recipe to an ordered process sequence (rooms + manpower types). Set default batch size and per-process durations.
  4. 4Ingredient availability check: Review Production Inventory → Live Stock. If insufficient raw materials are on hand, raise an Ingredient Request against the Warehouse.
  5. 5Ingredient Request fulfilled: Warehouse approves and delivers. Production confirms receipt in Production In/Out → In. Ingredients move from "Expecting" to "Existing" in Production Inventory.
  6. 6Job scheduled: In Production Scheduler, click Insert Job → select the template → drag onto the timeline → assign workers → Save Schedule.
  7. 7Production runs: Batch status advances to In Progress. Production staff use Schedule Views (Room View / User View) for shift-level instructions.
  8. 8Batch completes → QC: Status changes to Awaiting QC. QC officer records checks in Production QC and marks Pass, Fail, or Rework. Failed batches are written off; rework batches re-enter the Scheduler.
  9. 9QC Passed → Finished Goods: Batch appears in Finished Goods as a pending transfer. Costing is calculated automatically at this point.
  10. 10Transfer to Warehouse: Production initiates the transfer via Production In/Out → Out. Status changes to Dispatched.
  11. 11Warehouse receives: Warehouse confirms quantities and marks the transfer Received. Finished Goods SKU is added to Warehouse inventory.
  12. 12Available for sale: Warehouse inventory is live — the product can now be allocated to Sales Orders and dispatched to customers via the Outbound module.

Finance Module

The Finance module covers two areas: Bank Reconciliation (matching bank statement lines to outlet payment records) and Invoices (AP supplier invoices and AR customer invoices).

Access requires: finance.overview.read (Finance Overview), finance.reconciliation.read (view reconciliation), finance.reconciliation.write (create/edit), finance.reconciliation.admin (lock periods, journal export), finance.invoices.read (invoice visibility). Assign the built-in Finance Manager role or create a custom role with the required permissions.

Bank Reconciliation — Overview

Bank Reconciliation works on monthly periods. Each period holds uploaded bank statement transactions, per-category reconciliation state, parked entries, and journal adjustments. Periods can be re-opened until explicitly locked.

  1. 1Create a period — Finance → Bank Reconciliation → New Period. Select month and year.
  2. 2Upload bank statement — Click Upload Statement. Accepts CSV or Excel. The system auto-categorises each transaction row by description keyword (e.g. "ALLINPAY" → Kpay, "GPAY" → Grab).
  3. 3Reconcile by category — Click each category tile. The right panel shows the matching logic and lets you mark the category reconciled once the difference is zero.
  4. 4Park exceptions — For transactions that cannot be matched, create a Parked Entry. Optionally flag it as an Independent Journal Entry so it is included in the export regardless of park state.
  5. 5Journal adjustments — Add standalone journal entries (debit/credit pairs) for items like bank charges, interest, or corrections that have no corresponding bank transaction.
  6. 6Lock period — Once all categories reconcile and the comparison totals show zero difference, click Complete Period. This prevents further edits.
  7. 7Export journal entries — Click Create Journal Entries to download a CSV of all adjustments for the period for posting into your accounting system.

Category Reconciliation Rules

Each category has its own matching logic. Understanding the rules prevents reconciliation errors.

Grab

Bank transactions identified by GPAY / GRAY NETWORK / FAST GRAY keywords. Matching is sum-based by outlet UID — the bank payout for a given outlet UID must equal the sum of all Grab system amounts for that outlet's UID. Outlet UIDs are mapped to locations (Marina Square → 65383, Orchard Gateway → 33861, Vivo → 80569). Category completes when every outlet UID's bank sum matches its Grab sum.

Kpay (Allinpay)

Bank transactions identified by ALLINPAY keyword. Matching is session-based by outlet name — each bank transaction is matched to a Kpay session with the same outlet and a close amount. Multiple sessions per outlet are possible. Category completes when all bank transactions are matched to sessions with zero unmatched remainder.

Foodpanda

Bank transactions identified by DELIVERY HERO / FOODPANDA keywords. Matching is per-outlet session — each Foodpanda payout references a 4-character outlet code (GEYA = Marina Square, EL8T = Orchard Gateway, LTR0 = Vivo, B7PL = Westgate). Each payout is matched to the Foodpanda system records for that outlet code. Category completes when every payout is matched.

Tabsquare

Bank transactions identified by ADYEN keyword. Matching is month sum-based — the sum of all Tabsquare bank payouts for the period must equal the total Tabsquare system report for the month. No per-outlet breakdown. Single difference check.

Shopback

Bank transactions identified by SHOPBACK keyword. Matching is total sum — the sum of all Shopback bank transactions must equal the total Shopback system report for the period. Single difference check.

Cash Deposit

Bank transactions identified by CASH DEPOSIT / CASH DEP / CDM keywords. Matching is individual checkbox — each cash deposit transaction must be manually checked off against a corresponding outlet cash count record. All transactions must be matched (checked) for the category to complete.

Svc Chg (Service Charges)

Bank transactions identified by SERVICE CHARGE / SVC CHG / SC / BANK CHARGE / BK CHG keywords. These are bank fees and charges — no reconciliation required. The category auto-completes. Transactions are listed for reference only.

Others

Any transaction not matched by the above keyword rules falls into Others. These are handled manually: create a journal entry for each unmatched item, selecting the correct account code (debit/credit). The category can be marked complete even if the running difference is non-zero, because Others uses journal entries as the authoritative record rather than a sum match.

Deliveroo

Bank transactions identified by DELIVEROO keyword. Matching works similarly to Foodpanda — each payout is matched to the Deliveroo system report for the corresponding outlet and period.

Parked Entries

Parked entries are temporary holding records for transactions that need follow-up before they can be reconciled. They are per-category and per-period.

FieldDescription
DescriptionWhat this parked entry represents
AmountThe unmatched amount being parked
Independent JEWhen checked, the entry is saved to the database and included in journal exports permanently — even after unparking

When a parked entry is resolved, click Unpark — the entry is removed and the running difference in the category updates immediately. Parked entries with Independent JE checked persist in the journal adjustment log even after unparking.

Parked entries temporarily inflate the "unreconciled" count in a category. Do not mark a category complete while there are outstanding parked entries unless you have intentionally journalled them as Independent JEs.

Journal Adjustments

Journal adjustments are standalone double-entry records that are always included in the period's journal export. Unlike parked entries they are not tied to a specific bank transaction.

Use cases: bank interest income, bank charges not categorised above, rounding adjustments, contra entries for prior-period corrections.

Each entry requires: Date, Description, Account Code, Debit amount, Credit amount. The entry is saved permanently and survives park/unpark cycles in the same period.

Journal adjustments are also auto-created when outlet category entries are captured from the Grab, Kpay, Foodpanda, and Tabsquare panels — the system creates the corresponding JE automatically so the journal export is always complete.

Invoices (AP & AR)

The Finance module provides a read-only view of all invoices in the system. Supplier invoices (AP) are created when a GRN is posted. Customer invoices (AR) are created when a Delivery Order is marked delivered.

TypeSourceActions available in Finance
Supplier Invoice (AP)Auto-created from posted GRNView details, mark paid, add supplier reference
Customer Invoice (AR)Auto-created from delivered DOView details, mark paid, confirm

Full invoice editing (amounts, line items) is done in Inbound → Supplier Invoices and Outbound → Customer Invoices respectively. The Finance view is for payment tracking and overview.

User Management

Accessible via Management → User Management. Requires management.users.read. The page has two tabs: Users and Roles.

Creating a User

Requires management.users.create (shows the Add User button).

  1. 1Click Add User (top-right of the User Management page).
  2. 2Fill in Full Name, Email, Department, and select an initial Role.
  3. 3Click Create User. Default password is changeme123 — the user must change it on first login.
  4. 4If email notifications are configured, the new user receives a welcome email with their credentials automatically.

Managing User Roles

Requires management.users.assign_roles. Click the icon on any user row to open the Assign Roles modal. Tick the roles to grant — changes take effect on next login.

Password Reset

Requires management.users.reset_password. Click the key icon → Generate Password. The temporary password is shown on screen and optionally emailed to the user. It is not shown again after the modal is closed.

Edit User Profile

Requires management.users.update_profile. Click the pen icon to change the user's display name, department, or account status (active/inactive).

Lock / Unlock Accounts

Requires management.users.lock_unlock. Click the lock icon to lock an account. Locked users cannot log in even with the correct password. Unlock by clicking again.

Roles Tab

Requires management.users.assign_roles to create or edit roles. The Roles tab shows all roles with their user count and permission breakdown. Click New Role to create a custom role with a hand-picked permission set. Click Edit to modify an existing role's grants. Click Delete to remove an unused role (blocked if users are assigned to it).

Super Admin protection: The super_admin and erp_admin roles are permanently protected — their Edit and Delete buttons are hidden. Users who hold the super_admin role are also protected: their Edit, Reset Password, Lock/Unlock, and Assign Roles actions are hidden from all non-superadmin operators. Only another Super Admin can manage a Super Admin account. The super_admin role is not visible in the role dropdown when creating a user or assigning roles, unless the operator is themselves a Super Admin. This prevents privilege escalation.

Setting Up a Finance Department User (Example)

  1. 1Create the user account with department = Finance.
  2. 2Open Assign Roles and tick Finance Manager (grants finance.* plus read access to inbound/outbound overviews).
  3. 3Or create a custom role: New Role → tick finance.overview.read, finance.reconciliation.read, finance.reconciliation.write, finance.invoices.read.
  4. 4The user can now access Finance → Finance Overview and Finance → Bank Reconciliation on their next login.

Setting Up an Operations Head User (Example)

  1. 1Create the user account with department = Operations.
  2. 2Assign the Management Admin role (grants management.*, including management.users.create and management.users.assign_roles).
  3. 3The user can now create users, edit roles, and assign permissions to other staff — but cannot edit or assign the Super Admin role unless they are themselves a Super Admin.

Email Notifications

The system can send automated emails for key events. Configure SMTP settings in Management → Notifications.

Setting Up Email (SMTP)

  1. 1Go to Management → Notifications.
  2. 2Toggle Email Notifications to Enabled.
  3. 3Enter your SMTP details: host, port, username, and password.
  4. 4Enter a test email address and click Send Test to verify the connection.
  5. 5Enable individual notification triggers as needed.
  6. 6Click Save Notification Settings.

Gmail users: You must use an App Password, not your regular Google password. Generate one at: Google Account → Security → 2-Step Verification → App Passwords. SMTP Host: smtp.gmail.com, Port: 587.

Available Notification Triggers

TriggerWhen it firesRecipient
New User CreatedAdmin creates a new user accountThe new user (welcome email with credentials)
Password ResetAdmin resets a user's passwordThe affected user (temp password email)
PO ApprovedA purchase order is approvedPO Recipients group (configurable)
SO ApprovedA sales order is approved and picking startsSO Recipients group (configurable)
Low Stock AlertSKU quantity drops below minimum levelLow Stock Recipients group (configurable)

Email Log

The bottom of the Notifications settings page shows a log of all emails sent, their status (sent / failed), and error messages for failed attempts. Click Refresh to update.

System Settings

Accessible via Management → Tax & Finance Settings. Requires management.settings.read.

SettingDescription
Outbound Tax Rate (%)Applied to all Sales Orders and Customer Invoices
Inbound Tax Rate (%)Applied to all Purchase Orders and Supplier Invoices
Default Payment TermsDefault days for new customer accounts
Credit Limit WarningAlert when a customer has used this % of their credit limit
Currency CodeISO 4217 code (e.g. SGD, USD, MYR)
Currency SymbolDisplayed prefix (e.g. $, RM, £)
Require PO ApprovalIf on, POs must be approved before being sent to suppliers
Require SO ApprovalIf on, SOs must be approved before picking begins
Auto-Create Picking ListAutomatically generate a picking list when a SO is approved
Stock Valuation MethodFIFO (first-in first-out) or Weighted Average for cost calculations

File Repository & Import

Accessible via Management → File Repository. Serves as document storage, data export centre, and master data import hub.

Data Import (CSV)

Import master data directly from CSV files. Supported datasets:

DatasetKey FieldWhat gets overwritten
SKU CatalogueskuCodeProduct details, pricing, storage type
Warehouse LocationslocationIdLocation type, capacity, zone
Supplier DirectorycodeContact details, lead times
Customer DirectorycodeContact details, payment terms, credit limits

Import Workflow

  1. 1Click Template on the dataset card to download the CSV template with correct headers and sample data.
  2. 2Fill in your data following the template format. The key column (e.g. skuCode) identifies existing records to update.
  3. 3Click Import, select your CSV file. The system validates that all required headers are present.
  4. 4A preview shows the record count and first 5 rows. Review before confirming.
  5. 5Click Import & Overwrite. The system automatically archives the current data to the Archives folder before applying changes.
  6. 6A results summary shows how many records were created, updated, and skipped.

Automatic archiving: Before any import overwrites data, the current dataset is saved as a timestamped CSV in File Repository / Archives. You can download the archived file at any time to restore previous data.

Master Data Export

The Export Center card lets you export Suppliers, SKUs, Inventory, Users, Locations, and Roles in Excel, CSV, or JSON format in one click.

Key Workflows

🛒 Purchase-to-Pay (P2P)

Create PO Approve PO Send to Supplier Receive Goods (GRN) Post GRN → Stock Up Supplier Invoice

📦 Order-to-Cash (O2C)

Quotation Convert to SO Approve SO Pick Goods Stage Dispatch Deliver → Invoice

🏭 Production Cycle

Schedule Job Confirm Ingredients Start Batch Complete Batch QC Check To Finished Goods

Troubleshooting

ProblemLikely CauseFix
Blank screen / page won't loadUI server not runningRun npx serve -l 8888 . in the cookie-erp-ui folder
Login fails / API errorAPI server not runningRun npm run dev in cookie-erp-api folder
Tailscale user can't connectFirewall blocking port 8888 or 3000Run open-firewall-admin.bat as Administrator
Inventory / Locations show loading foreverAPI unreachable from browserCheck both servers are running; hard-refresh (Ctrl+Shift+R)
Email notifications not sendingSMTP not configured or disabledGo to Management → Notifications → configure SMTP → Send Test
CSV import fails header validationColumn headers don't match templateDownload the template, fill it in exactly — don't rename headers
"Access denied" on a pageYour role lacks the required permissionAsk an administrator to assign the correct role
Picking list not generating after SO approvalAuto-create picking list setting is offManagement → Tax & Finance Settings → enable Auto-Create Picking List