Skip to content

Latest commit

 

History

History
481 lines (355 loc) · 21 KB

File metadata and controls

481 lines (355 loc) · 21 KB

Project TODO for printavo-ruby

Full task list for printavo-ruby across all versions. Checked items are shipped.


Foundation

  • Scaffold gem with RSpec, GitHub Actions CI, MIT license
  • Printavo::Client — instance-based, multi-client capable entry point
  • Printavo::Connection — Faraday builder with email + token headers
  • Printavo::GraphqlClient — raw query interface over POST
  • Printavo::Error hierarchy (AuthenticationError, RateLimitError, NotFoundError, ApiError)
  • Faraday retry middleware (max 2 retries; 429/5xx)
  • RSpec + VCR + WebMock + Faker sanitization — 100% line coverage
  • SimpleCov + Coveralls coverage badge
  • Guard + RuboCop DX setup
  • bin/spec — multi-Ruby local test runner (reads versions from .mise.toml)
  • bin/lint — multi-Ruby RuboCop runner
  • GitHub Actions CI: Ruby 3.3 + Ruby 4.0 matrix
  • Automated RubyGems publish on v* tag via trusted publishing (release.yml)
  • Git pre-push hook: guards Gemfile.lock version sync and x86_64-linux platform
  • Client#login / Client#logout — raise NotImplementedError; gem uses header-based auth, not session mutations

Resources & Models

  • Customersall, find
  • Ordersall, find
  • Jobsall (by order), find
  • Statusesall, find, registry (O(1) Symbol lookup)
  • Inquiriesall, find
  • Printavo::Customer model
  • Printavo::Order model with status_key, status?, status_id, status_color
  • Printavo::Job model
  • Printavo::Status model with key (snake_case Symbol)
  • Printavo::Inquiry model

Mutations

  • GraphqlClient#mutate — semantic write method (same transport as query)
  • Customers#create(primary_contact:, **input)customerCreate
  • Customers#update(id, **input)customerUpdate
  • Orders#create(**input)quoteCreate
  • Orders#update(id, **input)quoteUpdate
  • Orders#update_status(id, status_id:)statusUpdate (handles OrderUnion via inline fragments)
  • Inquiries#create(**input)inquiryCreate
  • Inquiries#update(id, **input)inquiryUpdate
  • camelize_keys — snake_case → camelCase input conversion
  • build_customer / build_order — mutation response normalization helpers
  • Contacts#delete(id)contactDelete
  • Customers#delete(id)customerDelete
  • Inquiries#delete(id)inquiryDelete
  • Invoices#delete(id)invoiceDelete
  • Invoices#duplicate(id)invoiceDuplicate
  • Orders#delete(id)quoteDelete
  • Orders#duplicate(id)quoteDuplicate

Pagination

  • Printavo::Page — value object (records, has_next_page, end_cursor, to_a, size, empty?)
  • Resources::Base#each_page — cursor-following page enumerator
  • Resources::Base#all_pages — flat array across all pages
  • GraphqlClient#paginate — raw cursor pagination with dot-path resolution

Code Quality & DX

  • # frozen_string_literal: true on all 39 .rb files
  • Extract 17 GraphQL heredocs into external .graphql files (lib/printavo/graphql/<resource>/<op>.graphql)
  • docs/ consolidation — CHANGELOG.md, CONTRIBUTING.md, FUTURE.md, CACHING.md
  • docs/CACHING.md — nine caching strategy patterns for rate-limit-aware consumers
  • Split spec/support/factories.rb monolith into 9 domain files under spec/support/factories/

Webhooks

  • Printavo::Webhooks.verify — Rack-compatible HMAC-SHA256 signature verification
  • Webhook event type registry (map Printavo event names to Ruby symbols)
  • Rack middleware: Printavo::Webhooks::Middleware (verify + parse in one step)

API V2 Coverage Gaps

Resources and mutations present in the Printavo V2 GraphQL API that are not yet wrapped by a resource class. Raw GraphQL access works for all of these today via client.graphql.query(...) — these tasks add first-class resource support.

Embedded / Infrastructure Types (no standalone resource needed)

These types appear in the schema but are sub-objects, pagination wrappers, or return values — they are exposed via model field accessors, not separate resources.

  • *Connection / *Edge (all variants) — GraphQL pagination wrappers; handled by Printavo::Page
  • Address, BillingAddress, CustomerAddress, MerchAddress, CustomAddress — embedded address shapes
  • Avatar — embedded in User
  • CatalogInformation, InvoiceInformation — embedded in Account
  • DeletedID — return type for delete mutations
  • EmailMessage, TextMessage — message subtypes under Thread
  • Feature, FeatureRestriction — embedded in Account.features
  • LineItemEnabledColumns, LineItemGroupSize, LineItemPriceReceipt, LineItemSizeCount — embedded in LineItemGroup / LineItem
  • LoggedIn — auth response type for login / logout mutations; not wrapped — gem uses header-based auth. Both methods raise NotImplementedError on Printavo::Client with a message directing consumers to the email + token initializer pattern.
  • MerchOrderDelivery, MerchStoreSummary — embedded in MerchOrder / MerchStore
  • MessageAttachment — embedded in Thread messages
  • ObjectTimestampscreatedAt / updatedAt on all objects
  • OrderUnionConnection / OrderUnionEdge — union pagination for Quote | Invoice; handled via inline fragments
  • PageInfo — cursor pagination metadata; handled by Printavo::Page
  • PaymentRequestDetail — embedded in PaymentRequest
  • Permission — embedded in User
  • Personalization — size/color breakdown embedded in LineItem / Imprint
  • PricingMatrixCell, PricingMatrixColumn — sub-objects of PricingMatrix
  • ProductCatalog — configuration embedded in Account
  • Social — social media links embedded in Account
  • ThreadSummary — preview summary embedded on orders; not a standalone query
  • TransactionDetails, TransactionUnionConnection, TransactionUnionEdge — embedded / pagination wrappers

Account ✅

  • Printavo::Account model (shop-level info: name, address, phone, logo)
  • Account resource: find (singleton — no ID needed)
  • account query

Contacts ✅

  • Printavo::Contact model (id, firstName, lastName, email, phone)
  • Contacts resource: find(id), create, update
  • contact query (contacts are distinct from the customer's primaryContact)

Invoices ✅

  • Printavo::Invoice model (mirrors Order; has amountPaid, amountOutstanding, paidInFull?)
  • Invoices resource: all, find(id), update
  • client.invoices entry point on Printavo::Client

Approvals ✅

  • Printavo::ApprovalRequest model (id, status, sent_at, expires_at, contact)
  • ApprovalRequests resource: all(order_id:), find(id)
  • approvalRequestCreate mutation
  • approvalRequestApprove(id:) mutation
  • approvalRequestRevoke(id:) mutation
  • approvalRequestUnapprove(id:) mutation

Categories ✅

  • Printavo::Category model (id, name)
  • Categories resource: all, find(id) — reference data for products/line items

Contractor Profiles ✅

  • Printavo::ContractorProfile model (id, name, email)
  • ContractorProfiles resource: all, find(id) — contractors assignable to invoices

Custom Addresses ✅

  • Printavo::CustomAddress model (id, name, address, city, state, zip)
  • CustomAddresses resource: all(order_id:), find(id), create, update, delete
  • customAddressCreate / customAddressCreates (bulk) mutations
  • customAddressUpdate / customAddressUpdates (bulk) mutations
  • customAddressDelete / customAddressDeletes (bulk) mutations

Delivery Methods ✅

  • Printavo::DeliveryMethod model (id, name)
  • DeliveryMethods resource: all, find(id), create, update, archive
  • deliveryMethodCreate, deliveryMethodUpdate, deliveryMethodArchive mutations

Email Templates ✅

  • Printavo::EmailTemplate model (id, name, subject, body)
  • EmailTemplates resource: all, find(id)

Expenses ✅

  • Printavo::Expense model (id, name, amount, category)
  • Expenses resource: all(order_id:), find(id), create, update
  • expenseCreate, expenseUpdate mutations

Fees ✅

  • Printavo::Fee model (id, name, amount, taxable)
  • Fees resource: all(order_id:), find(id), create, update, delete
  • feeCreate / feeCreates (bulk) mutations
  • feeUpdate / feeUpdates (bulk) mutations
  • feeDelete / feeDeletes (bulk) mutations

Imprints ✅

  • Printavo::Imprint model (id, name, position, colors)
  • Imprints resource: all(line_item_group_id:), find(id), create, update, delete
  • imprintCreate / imprintCreates (bulk) mutations
  • imprintUpdate / imprintUpdates (bulk) mutations
  • imprintDelete / imprintDeletes (bulk) mutations
  • imprintMockupCreate / imprintMockupCreates (bulk) — attach mockup to imprint

Line Items ✅

  • Printavo::LineItem model (id, name, quantity, price, taxable)
  • LineItems resource: all(line_item_group_id:), find(id), create, update, delete
  • lineItemCreate / lineItemCreates (bulk) mutations
  • lineItemUpdate / lineItemUpdates (bulk) mutations
  • lineItemDelete / lineItemDeletes (bulk) mutations
  • lineItemMockupCreate / lineItemMockupCreates (bulk) — attach mockup to line item

Line Item Groups ✅

  • Printavo::LineItemGroup model (id, name, description)
  • LineItemGroups resource: all(order_id:), find(id), create, update, delete
  • lineItemGroupCreate / lineItemGroupCreates (bulk) mutations
  • lineItemGroupUpdate / lineItemGroupUpdates (bulk) mutations
  • lineItemGroupDelete / lineItemGroupDeletes (bulk) mutations

Merch ✅

  • Printavo::MerchStore model (id, name, url, summary)
  • Printavo::MerchOrder model (id, status, delivery, contact)
  • MerchStores resource: all, find(id)
  • MerchOrders resource: all, find(id)
  • client.merch_stores / client.merch_orders entry points

Mockups & Production Files ✅

  • Printavo::Mockup model (id, url, position, created_at)
  • Printavo::ProductionFile model (id, url, filename, created_at)
  • Mockups resource: all(order_id:), find(id), delete, deletes
  • mockupDelete / mockupDeletes (bulk) mutations
  • ProductionFiles resource: all(order_id:), find(id), create, creates, delete, deletes
  • productionFileCreate / productionFileCreates (bulk) mutations
  • productionFileDelete / productionFileDeletes (bulk) mutations

Payments ✅

  • Printavo::Payment model (id, amount, payment_method, paid_at)
  • Printavo::PaymentRequest model (id, amount, sent_at, paid_at, details)
  • Printavo::PaymentTerm model (id, name, net_days)
  • Payments resource: all(order_id:), find(id)
  • PaymentRequests resource: all(order_id:), find(id), create, delete
  • paymentRequestCreate, paymentRequestDelete mutations
  • PaymentTerms resource: all, find(id), create, update, archive
  • paymentTermCreate, paymentTermUpdate, paymentTermArchive mutations

Preset Tasks ✅

  • Printavo::PresetTask model (id, body, due_offset_days, assignee)
  • Printavo::PresetTaskGroup model (id, name, tasks)
  • PresetTasks resource: find(id), create, update, delete
  • presetTaskCreate, presetTaskUpdate, presetTaskDelete mutations
  • PresetTaskGroups resource: all, find(id), create, update, delete, apply
  • presetTaskGroupCreate, presetTaskGroupUpdate, presetTaskGroupDelete mutations
  • presetTaskGroupApply(id:, order_id:) mutation — applies a group to an order

Product Catalog & Pricing ✅

  • Printavo::Product model (id, name, sku, description)
  • Printavo::PricingMatrix model (id, name)
  • Products resource: all, find(id)
  • PricingMatrices resource: all, find(id)

Tasks ✅

  • Printavo::Task model (id, body, dueAt, completedAt, assignee)
  • Tasks resource: all, find(id), create, update, complete, delete
  • taskCreate, taskUpdate, taskDelete mutations

Threads (Messages) ✅

  • Printavo::Thread model (id, subject, createdAt, updatedAt)
  • Threads resource: all(order_id:), find(id), update
  • threadUpdate mutation
  • emailMessageCreate mutation — send an email message on a thread

Transactions ✅

  • Printavo::Transaction model (id, amount, kind, createdAt)
  • Transactions resource: all(order_id:), find(id)
  • Printavo::TransactionPayment model (id, amount, paymentMethod, paidAt, note)
  • TransactionPayments resource: create, update, delete
  • transactionPaymentCreate, transactionPaymentUpdate, transactionPaymentDelete mutations

Types of Work ✅

  • Printavo::TypeOfWork model (id, name)
  • TypesOfWork resource: all — reference data for order categorization

Users ✅

  • Printavo::User model (id, first_name, last_name, email, full_name)
  • Users resource: all, find(id) — shop staff members

Vendors ✅

  • Printavo::Vendor model (id, name, email, phone)
  • Vendors resource: all, find(id) — read-only; no create/update/delete in V2 API

Planned Versions

v0.6.0 — Invoices, Contacts & Account ✅

  • Invoices resource (all, find, update)
  • Contacts resource (find, create, update)
  • Account resource (singleton find)

v0.7.0 — Transactions, Tasks & Threads ✅

  • Transactions resource (all, find) + TransactionPayments (create, update, delete)
  • Tasks resource (all, find, create, update, complete, delete)
  • Threads resource (all, find, update) + emailMessageCreate

v0.8.0 — Order Structure: Line Items, Line Item Groups, Imprints & Fees ✅

  • LineItems resource (all, find, create/creates, update/updates, delete/deletes)
  • LineItemGroups resource (all, find, create/creates, update/updates, delete/deletes)
  • Imprints resource (all, find, create/creates, update/updates, delete/deletes, mockup attach)
  • Fees resource (all, find, create/creates, update/updates, delete/deletes)
  • Expenses resource (all, find, create, update)

v0.9.0 — Merch, Products & Pricing ✅

  • MerchStores + MerchOrders resources
  • Products resource + PricingMatrices resource
  • Categories resource (reference data)

v0.10.0 — Financial: Payments, Payment Terms & Requests ✅

  • Payments resource (all, find)
  • PaymentRequests resource (all, find, create, delete)
  • PaymentTerms resource (all, find, create, update, archive)

v0.11.0 — Workflow: Approvals & Preset Tasks ✅

  • ApprovalRequests resource (all, find, create, approve, revoke, unapprove)
  • PresetTasks resource (find, create, update, delete)
  • PresetTaskGroups resource (all, find, create, update, delete, apply)

v0.12.0 — Files, Media & Communication ✅

  • ProductionFiles resource (all, find, create/creates, delete/deletes)
  • Mockups resource (all, find, delete/deletes)
  • EmailTemplates resource (all, find)
  • CustomAddresses resource (all, find, create/creates, update/updates, delete/deletes)

v0.13.0 — People, Orgs & Reference Data ✅

  • Users resource (all, find)
  • Vendors resource (all, find) — read-only
  • ContractorProfiles resource (all, find)
  • DeliveryMethods resource (all, find, create, update, archive)
  • TypesOfWork resource (all)

v0.14.0 — Delete & Duplicate Mutations for Shipped Resources ✅

  • Contacts#deletecontactDelete
  • Customers#deletecustomerDelete
  • Inquiries#deleteinquiryDelete
  • Invoices#deleteinvoiceDelete
  • Invoices#duplicateinvoiceDuplicate
  • Orders#deletequoteDelete
  • Orders#duplicatequoteDuplicate

v0.15.0 — Retry / Backoff & CLI ✅

  • Configurable max_retries on Printavo::Client
  • Exponential backoff with jitter on 429 responses
  • retry_on_rate_limit: true/false client option
  • Thor-based printavo CLI (customers, orders, orders find <id>)

v0.16.0 — Enums ✅

  • Printavo::Enums::ApprovalRequestStatus
  • Printavo::Enums::ContactSortField
  • Printavo::Enums::LineItemSize
  • Printavo::Enums::LineItemStatus
  • Printavo::Enums::MerchOrderDeliveryMethod
  • Printavo::Enums::MerchOrderStatus
  • Printavo::Enums::MerchStoreStatus
  • Printavo::Enums::MessageDeliveryStatus
  • Printavo::Enums::OrderPaymentStatus
  • Printavo::Enums::OrderSortField
  • Printavo::Enums::PaymentDisputeStatusField
  • Printavo::Enums::PaymentRequestStatus
  • Printavo::Enums::PoGoodsStatus
  • Printavo::Enums::StatusType
  • Printavo::Enums::TaskSortField
  • Printavo::Enums::TaskableType
  • Printavo::Enums::TransactionCategory
  • Printavo::Enums::TransactionSource

v0.17.0 — GraphQL Interface Field Coverage ✅

  • VisualIDed interface — visualId on all applicable models
  • Timestamps interface — createdAt / updatedAt on all applicable models
  • MailAddress interface — address fields on all applicable models

v0.18.0 — Built-In Cache Adapter ✅

  • Optional cache: kwarg on Printavo::Client (any Rails.cache-compatible store)
  • Printavo::MemoryStore — thread-safe TTL-aware in-memory store (no Rails dependency)
  • GraphqlClient caching: #query is cache-aware; #mutate always bypasses
  • Stable SHA-256 cache key from normalized query + variables
  • default_ttl: 300 configurable per-client
  • docs/CACHING.md updated with built-in adapter usage examples

v0.18.1 — Examples: Diagramming & Reporting

  • examples/diagramming/workflow_diagram.rb — Mermaid, DOT, ASCII, SVG (dot CLI + ruby-graphviz gem)
  • examples/reporting/sales_report.rb — today, week, month, quarter, YTD, last year, custom range
  • examples/reporting/sales_tax_report.rb — invoice-level estimates + fee-level taxable detail
  • examples/reporting/customers_export.rb — CSV, XLSX, XLS, vCard (.vcf), HubSpot, Salesforce, Mailchimp, Constant Contact, Beehiiv, Brevo, ActiveCampaign
  • examples/reporting/outstanding_tasks.rb — overdue, due today, this week, upcoming, no due date; by-assignee summary; HTML calendar export
  • docs/FUTURE.md — Workflow Diagram section replaced with examples reference and rationale

v0.99.0 — API Freeze

  • Community feedback integration
  • Deprecation notices for any renamed methods
  • Full YARD API reference
  • Final documentation pass before 1.0

v1.0.0 — Stable SDK

  • Semver stability guarantee
  • Migration guide from 0.x

Future / Stretch Goals

Client-Side Aggregation Helpers

Note: Printavo's V2 GraphQL API exposes no pre-aggregated analytics or reporting endpoints. All "analytics" must be computed locally by paging through existing resources. A cache adapter (see below) is a prerequisite before these helpers would be practical in production.

  • Invoices#revenue_summary(after:, before:) — page invoices, return total/count/average
  • Orders#status_breakdown — group order count by status key
  • Customers#top(limit:, by:) — rank customers by order count or revenue
  • Orders#avg_turnaround — average time from created_at to most recent updated_at

Built-In Cache Adapter ✅ (v0.18.0)

  • Optional cache: kwarg on Printavo::Client
  • Duck-typed adapter interface: fetch(key, expires_in:) { } / delete(key) — matches Rails.cache
  • Printavo::MemoryStore — thread-safe in-memory store for non-Rails usage
  • GraphqlClient#query is cache-aware; #mutate always bypasses cache
  • Stable SHA-256 cache key from normalized query + variables
  • default_ttl: 300 configurable per-client

Workflow Diagram Generation

  • client.workflow.diagram(format: :svg) — visual status flowchart
  • ruby-graphviz backend (DOT → SVG/PNG)
  • Mermaid output option (embed in GitHub markdown)

Colophon

MIT License

©2026 Stan Carver II

Made in Texas