Vataman.org
The internal work OS for digital advertising agencies.
Vataman.org V1 is a lean, source-agnostic domain spine for importing and collaborating on advertising campaigns. It is currently designed as an internal-only tool to manage campaign strategy, human decisions, and execution checklists on top of raw imported change history.
We're moving our work here, also because the upwork dashboard is obsolete for this era. We will, in future releases, start tracking 'human hours' and 'agent hours' spent per client and bill accordingly. The multitenant separation of org work (vataman.org) and client work will provide clarity (did we do client work or spend time optimizing internal processes from client data).
Future releases will integrate with the Google Ads API, Meta Ads API, Upwork API, LinkedIn API, and Whatsapp Web API and the G-suite. This will be the unified surface that glues everything together. The Message model will be agnostic to source.
V1 Domain Spine
The core of Vataman.org is built around a source-agnostic domain model:
Organization: Represents the client.Campaign: Imported from external sources (e.g., Google Ads). Owns source-specific fields securely while exposing local fields forgoal,strategy, andconstraints.CampaignChange: Raw, normalized, append-only records of source change history.CampaignDecision: Human rationale and strategic pivots recorded by agency members.CampaignChecklistItem: Thin execution state tracking per campaign.
Upwork API Integration
Vataman.org integrates with the Upwork GraphQL API to enrich organization context with client work feeds.
- Environment: Set
UPWORK_API_KEYin your.envfile to your personal-context Upwork developer key. - Sync: Run
bin/rails upwork:syncor use the Sync Upwork button on the organization detail page (Admins only).
This integration imports client context, contracts, jobs, and proposals. It also generates organization events for a unified timeline alongside Google Ads campaign changes.
Archive-to-API Compatibility Contract
This local importer is a placeholder for future Google Ads API sync, not a live API integration. The source-owned spine mirrors API identities we need later, including resource_name, parent IDs, and enum text. Metrics and segments are validation-only and are not persisted. See .omo/evidence/google-ads-field-retention-matrix.md for the normalize/metadata/discard contract. Use the redacted fixtures in test/fixtures/files/google_ads/ for parser coverage, keep raw archive data out of the repo, and treat live Google Ads API sync as future work.
Strict Import Policy
The importer is atomic and idempotent. If any selected source export contains an unmapped shape or parsing error, the entire import run will fail before writing to the database, outputting actionable validation errors.
Development
Prerequisites
- Ruby 3.4.5
- PostgreSQL
- Node.js & Yarn
Setup
bundle installyarn installbin/rails db:setup(Seedsmihailpaleologu@gmail.comandeugenvman@gmail.comas admins)bin/devto start the application
Testing & Verification
The project uses Minitest and Selenium for system tests.
- Unit & System Tests:
bin/rails test && bin/rails test:system - Linting:
bin/rubocop && bin/erb_lint --lint-all - Formatting:
npx prettier --check .(Prettier is configured to ignore the local archive path)
Project Notes
This codebase evolved from a multi-tenant boilerplate. Legacy elements such as subscriptions, payments, and third-party admin panels have been stripped out to focus on the campaign domain spine. Flipper remains available as an internal operator feature-flag utility.