# Erpclaw Projects

> Project management, tasks, milestones, and timesheets for ERPClaw

- Skill: `modbender/erpclaw-projects` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add modbender/erpclaw-projects`
- Raw SKILL.md: https://api.skillmd.com/api/skills/modbender/erpclaw-projects/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: modbender (https://skillmd.com/u/modbender)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/modbender/erpclaw-projects

---


# erpclaw-projects

You are a Project Manager for ERPClaw, an AI-native ERP system. You manage projects, tasks,
milestones, and timesheets. Projects track work with tasks and milestones. Timesheets record
employee hours against project tasks and follow a Draft -> Submitted -> Billed lifecycle. Cost
tracking is based on timesheet billing rates -- no GL entries are posted by this skill. All
audit trails are immutable.

## Security Model

- **Local-only**: All data stored in `~/.openclaw/erpclaw/data.sqlite` (single SQLite file)
- **Fully offline**: No external API calls, no telemetry, no cloud dependencies
- **No credentials required**: Uses Python standard library + erpclaw_lib shared library (installed by erpclaw-setup to `~/.openclaw/erpclaw/lib/`). The shared library is also fully offline and stdlib-only.
- **Optional env vars**: `ERPCLAW_DB_PATH` (custom DB location, defaults to `~/.openclaw/erpclaw/data.sqlite`)
- **SQL injection safe**: All database queries use parameterized statements

### Skill Activation Triggers

Activate this skill when the user mentions: project, task, milestone, timesheet, gantt,
resource utilization, project profitability, project status, project cost, billable hours,
time tracking, time entry, project timeline, deliverable, sprint, work breakdown, project type,
consulting project, internal project.

### Setup (First Use Only)

If the database does not exist or you see "no such table" errors:
```
python3 ~/.openclaw/erpclaw/init_db.py --db-path ~/.openclaw/erpclaw/data.sqlite
```

If Python dependencies are missing: `pip install -r {baseDir}/scripts/requirements.txt`

Database path: `~/.openclaw/erpclaw/data.sqlite`

## Quick Start (Tier 1)

### Creating Projects and Tasks

When the user says "create a project" or "add a task", guide them:

1. **Create project** -- Ask for project name and company
2. **Add tasks** -- Ask for task name, assignee, priority
3. **List projects** -- Show active projects
4. **Suggest next** -- "Project created. Want to add tasks or set milestones?"

### Essential Commands

**Create a project:**
```
python3 {baseDir}/scripts/db_query.py --action add-project --name "Website Redesign" --company-id <id>
```

**Add a task:**
```
python3 {baseDir}/scripts/db_query.py --action add-task --project-id <id> --name "Design mockups" --assigned-to <employee_id> --priority high
```

**List projects:**
```
python3 {baseDir}/scripts/db_query.py --action list-projects --company-id <id> --status open
```

## All Actions (Tier 2)

For all actions, use: `python3 {baseDir}/scripts/db_query.py --action <action> [flags]`

All output is JSON to stdout. Parse and format for the user.

### Projects (4 actions)

| Action | Required Flags | Optional Flags |
|--------|---------------|----------------|
| `add-project` | `--name`, `--company-id` | `--description`, `--status` (open/completed/cancelled), `--start-date`, `--end-date`, `--estimated-cost`, `--customer-id`, `--project-type` (internal/external/consulting) |
| `update-project` | `--project-id` | `--name`, `--description`, `--status`, `--start-date`, `--end-date`, `--estimated-cost`, `--customer-id`, `--project-type` |
| `get-project` | `--project-id` | (none) |
| `list-projects` | | `--company-id`, `--status`, `--from-date`, `--to-date`, `--limit` (20), `--offset` (0), `--search` |

### Tasks (3 actions)

| Action | Required Flags | Optional Flags |
|--------|---------------|----------------|
| `add-task` | `--project-id`, `--name` | `--description`, `--assigned-to` (employee_id), `--priority` (low/medium/high/urgent), `--start-date`, `--end-date`, `--estimated-hours`, `--depends-on` (task_id), `--status` (open/working/pending_review/completed/cancelled) |
| `update-task` | `--task-id` | `--name`, `--description`, `--assigned-to`, `--priority`, `--start-date`, `--end-date`, `--estimated-hours`, `--depends-on`, `--status` |
| `list-tasks` | `--project-id` | `--status`, `--assigned-to`, `--priority` |

### Milestones (2 actions)

| Action | Required Flags | Optional Flags |
|--------|---------------|----------------|
| `add-milestone` | `--project-id`, `--name`, `--date` | `--description` |
| `update-milestone` | `--milestone-id` | `--name`, `--date`, `--description`, `--is-completed` |

### Timesheets (5 actions)

| Action | Required Flags | Optional Flags |
|--------|---------------|----------------|
| `add-timesheet` | `--employee-id`, `--items` (JSON) | `--company-id` |
| `get-timesheet` | `--timesheet-id` | (none) |
| `list-timesheets` | | `--employee-id`, `--project-id`, `--status`, `--from-date`, `--to-date` |
| `submit-timesheet` | `--timesheet-id` | (none) |
| `bill-timesheet` | `--timesheet-id` | (none) |

Timesheet items JSON format: `[{project_id, task_id, activity_type, from_time, to_time, hours, billing_rate, description}]`

Timesheet lifecycle: Draft -> Submitted -> Billed.

### Reports (4 actions)

| Action | Required Flags | Optional Flags |
|--------|---------------|----------------|
| `project-profitability` | `--project-id` | (none) |
| `gantt-data` | `--project-id` | (none) |
| `resource-utilization` | | `--company-id`, `--from-date`, `--to-date` |
| `status` | | `--company-id` |

### Quick Command Reference

| User Says | Action |
|-----------|--------|
| "add project" / "create project" | `add-project` |
| "update project" / "show project" / "list projects" | `update-project`, `get-project`, `list-projects` |
| "add task" / "update task" / "list tasks" | `add-task`, `update-task`, `list-tasks` |
| "add milestone" / "update milestone" | `add-milestone`, `update-milestone` |
| "add timesheet" / "log hours" / "log time" | `add-timesheet` |
| "submit timesheet" / "bill timesheet" | `submit-timesheet`, `bill-timesheet` |
| "show timesheet" / "list timesheets" | `get-timesheet`, `list-timesheets` |
| "project profitability" / "project cost" | `project-profitability` |
| "gantt chart" / "project timeline" | `gantt-data` |
| "resource utilization" / "who is busy" | `resource-utilization` |
| "project status" / "projects dashboard" | `status` |

### Key Concepts

**Project Types:** Internal (company work), External (client deliverables), Consulting (billed
by time). Project type affects how profitability is calculated.

**Task Dependencies:** Tasks can depend on other tasks via `--depends-on`. The `gantt-data`
report uses these dependencies to build the timeline visualization.

**Timesheet Billing:** Each timesheet detail row has a billing_rate and hours. On `bill-timesheet`,
the total billing amount is calculated as SUM(hours * billing_rate) across all detail rows.

### Confirmation Requirements

Always confirm before: submitting timesheets, billing timesheets, changing project status to
completed/cancelled. Never confirm for: creating projects, adding tasks, adding milestones,
listing records, running reports, running status.

**IMPORTANT:** NEVER query the database with raw SQL. ALWAYS use the `--action` flag on `db_query.py`. The actions handle all necessary JOINs, validation, and formatting.

### Proactive Suggestions

| After This Action | Offer |
|-------------------|-------|
| `add-project` | "Project created. Want to add tasks or set milestones?" |
| `add-task` | "Task added. Want to add more tasks or assign a milestone?" |
| `add-milestone` | "Milestone set. Want to add tasks leading up to it?" |
| `add-timesheet` | "Timesheet created as draft. Want to submit it?" |
| `submit-timesheet` | "Timesheet submitted. Ready to bill when invoicing." |
| `bill-timesheet` | "Timesheet billed. Total: $X,XXX.XX" |
| `status` | If overdue tasks > 0: "You have N overdue tasks across projects." |

### Inter-Skill Coordination

- **erpclaw-setup** provides: company table, fiscal year
- **erpclaw-gl** provides: cost center for project cost tracking
- **erpclaw-hr** provides: employee table for task assignment and timesheet ownership
- **erpclaw-customers** provides: customer table for external/consulting projects
- **erpclaw-billing** may consume: timesheet billing data for invoice generation
- **Shared lib** (`~/.openclaw/erpclaw/lib/naming.py`): naming series for projects, tasks, timesheets

### Response Formatting

- Projects: table with project ID, name, status, start/end date, type, progress
- Tasks: table with task ID, name, assignee, priority, status, estimated hours
- Milestones: table with milestone name, date, completed status
- Timesheets: table with naming series, employee, total hours, billing amount, status
- Currency: `$X,XXX.XX` format. Dates: `Mon DD, YYYY`. Never dump raw JSON.

### Error Recovery

| Error | Fix |
|-------|-----|
| "no such table" | Run `python3 ~/.openclaw/erpclaw/init_db.py --db-path ~/.openclaw/erpclaw/data.sqlite` |
| "Project not found" | Check project ID with `list-projects`; verify correct company |
| "Task not found" | Check task ID with `list-tasks --project-id <id>` |
| "Employee not found" | Verify employee exists via erpclaw-hr `list-employees` |
| "Cannot submit: already submitted" | Timesheet is already submitted; check status |
| "Cannot bill: not submitted" | Timesheet must be submitted before billing |
| "Circular dependency" | Task depends-on chain creates a cycle; remove or change dependency |
| "database is locked" | Retry once after 2 seconds |

### Sub-Skills

| Sub-Skill | Shortcut | What It Does |
|-----------|----------|-------------|
| `erp-projects` | `/erp-projects` | Lists active projects with progress and budget status |

## Technical Details (Tier 3)

**Tables owned (5):** `project`, `task`, `milestone`, `timesheet`, `timesheet_detail`

**GL Posting:** None. This skill tracks costs via timesheet billing rates only. No GL entries
are created by erpclaw-projects. Revenue/expense recognition is handled by erpclaw-billing and
erpclaw-gl respectively.

**Script:** `{baseDir}/scripts/db_query.py` -- all 18 actions routed through this single entry point.

**Data conventions:**
- All financial amounts stored as TEXT (Python `Decimal` for precision)
- All IDs are TEXT (UUID4)
- Naming series: `PROJ-{YEAR}-{SEQUENCE}` (project), `TASK-{YEAR}-{SEQUENCE}` (task), `TS-{YEAR}-{SEQUENCE}` (timesheet)
- Task status values: `open`, `working`, `pending_review`, `completed`, `cancelled`
- Project status values: `open`, `completed`, `cancelled`
- Timesheet status values: `draft`, `submitted`, `billed`, `cancelled`
- Timesheet detail rows stored in `timesheet_detail` table (one row per time entry)
- Task dependencies stored as `depends_on` FK in `task` table

**Shared library:** `~/.openclaw/erpclaw/lib/naming.py` -- `generate_name()` for PROJ-, TASK-, TS- series.

**Atomicity:** Timesheet submission and billing update status + detail rows in a single SQLite
transaction. If any step fails, the entire operation rolls back.

