Project TODO for printavo-ruby
Full task list for printavo-ruby across all versions. Checked items are shipped.
- Scaffold gem with RSpec, GitHub Actions CI, MIT license
-
Printavo::Client— instance-based, multi-client capable entry point -
Printavo::Connection— Faraday builder withemail+tokenheaders -
Printavo::GraphqlClient— rawqueryinterface over POST -
Printavo::Errorhierarchy (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.lockversion sync andx86_64-linuxplatform -
Client#login/Client#logout— raiseNotImplementedError; gem uses header-based auth, not session mutations
-
Customers—all,find -
Orders—all,find -
Jobs—all(by order),find -
Statuses—all,find,registry(O(1) Symbol lookup) -
Inquiries—all,find -
Printavo::Customermodel -
Printavo::Ordermodel withstatus_key,status?,status_id,status_color -
Printavo::Jobmodel -
Printavo::Statusmodel withkey(snake_case Symbol) -
Printavo::Inquirymodel
-
GraphqlClient#mutate— semantic write method (same transport asquery) -
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(handlesOrderUnionvia 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
-
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
-
# frozen_string_literal: trueon all 39.rbfiles - Extract 17 GraphQL heredocs into external
.graphqlfiles (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.rbmonolith into 9 domain files underspec/support/factories/
-
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)
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.
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 byPrintavo::PageAddress,BillingAddress,CustomerAddress,MerchAddress,CustomAddress— embedded address shapesAvatar— embedded inUserCatalogInformation,InvoiceInformation— embedded inAccountDeletedID— return type for delete mutationsEmailMessage,TextMessage— message subtypes underThreadFeature,FeatureRestriction— embedded inAccount.featuresLineItemEnabledColumns,LineItemGroupSize,LineItemPriceReceipt,LineItemSizeCount— embedded inLineItemGroup/LineItemLoggedIn— auth response type forlogin/logoutmutations; not wrapped — gem uses header-based auth. Both methods raiseNotImplementedErroronPrintavo::Clientwith a message directing consumers to theemail+tokeninitializer pattern.MerchOrderDelivery,MerchStoreSummary— embedded inMerchOrder/MerchStoreMessageAttachment— embedded inThreadmessagesObjectTimestamps—createdAt/updatedAton all objectsOrderUnionConnection/OrderUnionEdge— union pagination forQuote | Invoice; handled via inline fragmentsPageInfo— cursor pagination metadata; handled byPrintavo::PagePaymentRequestDetail— embedded inPaymentRequestPermission— embedded inUserPersonalization— size/color breakdown embedded inLineItem/ImprintPricingMatrixCell,PricingMatrixColumn— sub-objects ofPricingMatrixProductCatalog— configuration embedded inAccountSocial— social media links embedded inAccountThreadSummary— preview summary embedded on orders; not a standalone queryTransactionDetails,TransactionUnionConnection,TransactionUnionEdge— embedded / pagination wrappers
-
Printavo::Accountmodel (shop-level info: name, address, phone, logo) -
Accountresource:find(singleton — no ID needed) -
accountquery
-
Printavo::Contactmodel (id,firstName,lastName,email,phone) -
Contactsresource:find(id),create,update -
contactquery (contacts are distinct from the customer'sprimaryContact)
-
Printavo::Invoicemodel (mirrors Order; hasamountPaid,amountOutstanding,paidInFull?) -
Invoicesresource:all,find(id),update -
client.invoicesentry point onPrintavo::Client
-
Printavo::ApprovalRequestmodel (id,status,sent_at,expires_at,contact) -
ApprovalRequestsresource:all(order_id:),find(id) -
approvalRequestCreatemutation -
approvalRequestApprove(id:)mutation -
approvalRequestRevoke(id:)mutation -
approvalRequestUnapprove(id:)mutation
-
Printavo::Categorymodel (id,name) -
Categoriesresource:all,find(id)— reference data for products/line items
-
Printavo::ContractorProfilemodel (id,name,email) -
ContractorProfilesresource:all,find(id)— contractors assignable to invoices
-
Printavo::CustomAddressmodel (id,name,address,city,state,zip) -
CustomAddressesresource:all(order_id:),find(id),create,update,delete -
customAddressCreate/customAddressCreates(bulk) mutations -
customAddressUpdate/customAddressUpdates(bulk) mutations -
customAddressDelete/customAddressDeletes(bulk) mutations
-
Printavo::DeliveryMethodmodel (id,name) -
DeliveryMethodsresource:all,find(id),create,update,archive -
deliveryMethodCreate,deliveryMethodUpdate,deliveryMethodArchivemutations
-
Printavo::EmailTemplatemodel (id,name,subject,body) -
EmailTemplatesresource:all,find(id)
-
Printavo::Expensemodel (id,name,amount,category) -
Expensesresource:all(order_id:),find(id),create,update -
expenseCreate,expenseUpdatemutations
-
Printavo::Feemodel (id,name,amount,taxable) -
Feesresource:all(order_id:),find(id),create,update,delete -
feeCreate/feeCreates(bulk) mutations -
feeUpdate/feeUpdates(bulk) mutations -
feeDelete/feeDeletes(bulk) mutations
-
Printavo::Imprintmodel (id,name,position,colors) -
Imprintsresource: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
-
Printavo::LineItemmodel (id,name,quantity,price,taxable) -
LineItemsresource: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
-
Printavo::LineItemGroupmodel (id,name,description) -
LineItemGroupsresource:all(order_id:),find(id),create,update,delete -
lineItemGroupCreate/lineItemGroupCreates(bulk) mutations -
lineItemGroupUpdate/lineItemGroupUpdates(bulk) mutations -
lineItemGroupDelete/lineItemGroupDeletes(bulk) mutations
-
Printavo::MerchStoremodel (id,name,url,summary) -
Printavo::MerchOrdermodel (id,status,delivery,contact) -
MerchStoresresource:all,find(id) -
MerchOrdersresource:all,find(id) -
client.merch_stores/client.merch_ordersentry points
-
Printavo::Mockupmodel (id,url,position,created_at) -
Printavo::ProductionFilemodel (id,url,filename,created_at) -
Mockupsresource:all(order_id:),find(id),delete,deletes -
mockupDelete/mockupDeletes(bulk) mutations -
ProductionFilesresource:all(order_id:),find(id),create,creates,delete,deletes -
productionFileCreate/productionFileCreates(bulk) mutations -
productionFileDelete/productionFileDeletes(bulk) mutations
-
Printavo::Paymentmodel (id,amount,payment_method,paid_at) -
Printavo::PaymentRequestmodel (id,amount,sent_at,paid_at,details) -
Printavo::PaymentTermmodel (id,name,net_days) -
Paymentsresource:all(order_id:),find(id) -
PaymentRequestsresource:all(order_id:),find(id),create,delete -
paymentRequestCreate,paymentRequestDeletemutations -
PaymentTermsresource:all,find(id),create,update,archive -
paymentTermCreate,paymentTermUpdate,paymentTermArchivemutations
-
Printavo::PresetTaskmodel (id,body,due_offset_days,assignee) -
Printavo::PresetTaskGroupmodel (id,name,tasks) -
PresetTasksresource:find(id),create,update,delete -
presetTaskCreate,presetTaskUpdate,presetTaskDeletemutations -
PresetTaskGroupsresource:all,find(id),create,update,delete,apply -
presetTaskGroupCreate,presetTaskGroupUpdate,presetTaskGroupDeletemutations -
presetTaskGroupApply(id:, order_id:)mutation — applies a group to an order
-
Printavo::Productmodel (id,name,sku,description) -
Printavo::PricingMatrixmodel (id,name) -
Productsresource:all,find(id) -
PricingMatricesresource:all,find(id)
-
Printavo::Taskmodel (id,body,dueAt,completedAt,assignee) -
Tasksresource:all,find(id),create,update,complete,delete -
taskCreate,taskUpdate,taskDeletemutations
-
Printavo::Threadmodel (id,subject,createdAt,updatedAt) -
Threadsresource:all(order_id:),find(id),update -
threadUpdatemutation -
emailMessageCreatemutation — send an email message on a thread
-
Printavo::Transactionmodel (id,amount,kind,createdAt) -
Transactionsresource:all(order_id:),find(id) -
Printavo::TransactionPaymentmodel (id,amount,paymentMethod,paidAt,note) -
TransactionPaymentsresource:create,update,delete -
transactionPaymentCreate,transactionPaymentUpdate,transactionPaymentDeletemutations
-
Printavo::TypeOfWorkmodel (id,name) -
TypesOfWorkresource:all— reference data for order categorization
-
Printavo::Usermodel (id,first_name,last_name,email,full_name) -
Usersresource:all,find(id)— shop staff members
-
Printavo::Vendormodel (id,name,email,phone) -
Vendorsresource:all,find(id)— read-only; no create/update/delete in V2 API
-
Invoicesresource (all,find,update) -
Contactsresource (find,create,update) -
Accountresource (singletonfind)
-
Transactionsresource (all,find) +TransactionPayments(create,update,delete) -
Tasksresource (all,find,create,update,complete,delete) -
Threadsresource (all,find,update) +emailMessageCreate
-
LineItemsresource (all,find,create/creates,update/updates,delete/deletes) -
LineItemGroupsresource (all,find,create/creates,update/updates,delete/deletes) -
Imprintsresource (all,find,create/creates,update/updates,delete/deletes, mockup attach) -
Feesresource (all,find,create/creates,update/updates,delete/deletes) -
Expensesresource (all,find,create,update)
-
MerchStores+MerchOrdersresources -
Productsresource +PricingMatricesresource -
Categoriesresource (reference data)
-
Paymentsresource (all,find) -
PaymentRequestsresource (all,find,create,delete) -
PaymentTermsresource (all,find,create,update,archive)
-
ApprovalRequestsresource (all,find,create,approve,revoke,unapprove) -
PresetTasksresource (find,create,update,delete) -
PresetTaskGroupsresource (all,find,create,update,delete,apply)
-
ProductionFilesresource (all,find,create/creates,delete/deletes) -
Mockupsresource (all,find,delete/deletes) -
EmailTemplatesresource (all,find) -
CustomAddressesresource (all,find,create/creates,update/updates,delete/deletes)
-
Usersresource (all,find) -
Vendorsresource (all,find) — read-only -
ContractorProfilesresource (all,find) -
DeliveryMethodsresource (all,find,create,update,archive) -
TypesOfWorkresource (all)
-
Contacts#delete—contactDelete -
Customers#delete—customerDelete -
Inquiries#delete—inquiryDelete -
Invoices#delete—invoiceDelete -
Invoices#duplicate—invoiceDuplicate -
Orders#delete—quoteDelete -
Orders#duplicate—quoteDuplicate
- Configurable
max_retriesonPrintavo::Client - Exponential backoff with jitter on 429 responses
-
retry_on_rate_limit: true/falseclient option - Thor-based
printavoCLI (customers,orders,orders find <id>)
-
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
-
VisualIDedinterface —visualIdon all applicable models -
Timestampsinterface —createdAt/updatedAton all applicable models -
MailAddressinterface — address fields on all applicable models
- Optional
cache:kwarg onPrintavo::Client(anyRails.cache-compatible store) -
Printavo::MemoryStore— thread-safe TTL-aware in-memory store (no Rails dependency) -
GraphqlClientcaching:#queryis cache-aware;#mutatealways bypasses - Stable SHA-256 cache key from normalized query + variables
-
default_ttl: 300configurable per-client -
docs/CACHING.mdupdated with built-in adapter usage examples
-
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
- Community feedback integration
- Deprecation notices for any renamed methods
- Full YARD API reference
- Final documentation pass before 1.0
- Semver stability guarantee
- Migration guide from 0.x
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 fromcreated_atto most recentupdated_at
- Optional
cache:kwarg onPrintavo::Client - Duck-typed adapter interface:
fetch(key, expires_in:) { }/delete(key)— matchesRails.cache -
Printavo::MemoryStore— thread-safe in-memory store for non-Rails usage -
GraphqlClient#queryis cache-aware;#mutatealways bypasses cache - Stable SHA-256 cache key from normalized query + variables
-
default_ttl: 300configurable per-client
-
client.workflow.diagram(format: :svg)— visual status flowchart -
ruby-graphvizbackend (DOT → SVG/PNG) - Mermaid output option (embed in GitHub markdown)
©2026 Stan Carver II
