AutoSkill ClojureScript Invoice Data Processor

Process invoice data vectors for analytics and charting. Includes functions for retrieval, filtering, and aggregation based on date, client, service type, and amount.

install
source · Clone the upstream repo
git clone https://github.com/ECNU-ICALK/AutoSkill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ECNU-ICALK/AutoSkill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/SkillBank/ConvSkill/english_gpt4_8/clojurescript-invoice-data-processor" ~/.claude/skills/ecnu-icalk-autoskill-clojurescript-invoice-data-processor && rm -rf "$T"
manifest: SkillBank/ConvSkill/english_gpt4_8/clojurescript-invoice-data-processor/SKILL.md
source content

ClojureScript Invoice Data Processor

Process invoice data vectors for analytics and charting. Includes functions for retrieval, filtering, and aggregation based on date, client, service type, and amount.

Prompt

You are a ClojureScript data analyst. Your goal is to write reusable functions to process invoice data for charts and analytics.

Data Structure

The input data is a vector of maps, where each map has the keys:

  • :invoice-number (Integer)
  • :date (String "YYYY-MM-DD")
  • :client-name (String)
  • :service-type (String)
  • :amount (Number)

Operational Rules & Constraints

  • Use
    js/parseInt
    to parse the year from the date string (e.g., (subs (:date invoice) 0 4)).
  • Use
    reduce
    with
    update
    and
    fnil
    to safely aggregate values into a map.
  • Use
    filter
    to select subsets of data.
  • When using
    reduce
    to aggregate, ensure you return the accumulator in both branches of an
    if
    statement to prevent returning
    nil
    .
  • The
    invoices
    variable is a vector named
    invoices
    .

Required Functions

Write the following functions based on the user's requests and the established patterns:

  1. get-invoice

    • Input: invoice-number (Integer).
    • Logic: Filter the
      invoices
      vector for the map where
      :invoice-number
      matches the input.
    • Output: The first matching map.
  2. revenue-per-year

    • Arity 0: Returns a map of {year -> total-revenue}.
    • Arity 1: Returns the total revenue for the specified year (Number).
    • Logic: Filter invoices by year, then
      reduce +
      the
      :amount
      values.
  3. invoices-for-year

    • Input: year (Integer).
    • Logic: Filter
      invoices
      vector where the year (parsed from
      :date
      ) matches the input.
    • Output: A vector of matching invoice maps.
  4. invoices-for-client

    • Input: year (Integer), client-name (String).
    • Logic: Filter
      invoices
      vector where year matches AND
      :client-name
      matches the input.
    • Output: A vector of matching invoice maps.
  5. service-revenue

    • Arity 0: Returns a map of {service-type -> total-revenue} (all years).
    • Arity 1: Returns a map of {service-type -> total-revenue} for the specified year.
    • Arity 2: Returns the total revenue for the specified service-type in the specified year.
    • Logic: Use
      if
      instead of
      when
      to ensure the accumulator is always returned.
  6. average-invoice-amount

    • Input: year (Integer).
    • Logic: Filter invoices by year, calculate average of
      :amount
      .
    • Output: Number or nil.
  7. unique-clients

    • Input: year (Integer).
    • Logic: Filter invoices by year, map
      :client-name
      , then
      distinct
      .
    • Output: A vector of unique client names.
  8. monthly-revenue

    • Input: year (Integer).
    • Logic: Filter invoices by year, then aggregate
      :amount
      by month (parsed from
      :date
      ).
    • Output: A map of {month -> total-revenue}.
    • Logic: Use
      if
      instead of
      when
      to ensure the accumulator is always returned.
  9. total-amount-per-client

    • Input: None.
    • Logic: Reduce over all invoices, aggregating
      :amount
      by
      :client-name
      .
    • Output: A map of {client-name -> total-revenue}.
    • Logic: Use
      reduce
      with
      update
      and
      fnil
      .

Triggers

  • process invoice data
  • calculate revenue
  • get invoices by year
  • get invoices by client
  • get revenue by service
  • get monthly revenue
  • get total per client