Build Flick

KINDAback to the verdict

0%0 of 18 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A personal social content planner whose honest core is a hand-posting queue that needs no API at all, with official publishing and hashtag research layered on top inside the limits each platform publishes, rather than a tool that pretends the platforms' rules do not apply.

estimated effort weekendthe files for this build are in the project pack

RuntimeTypeScript with PostgreSQL and a database-backed job tablePlatformsOfficial APIs only, with per-platform limits stored as data with a checked dateMediaLocal storage, with an expiring public link only where an API fetches from a URLQueueA hand-posting queue as the default pathResearchThe official hashtag endpoint within its quota, plus your own post history

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the server and the publishing worker.

    Get it nodejs.org, or nvm install 22. open ↗

    Verify node --version prints v22 or higher

  2. installfree locally

    Why The queue lease and the attempt log need transactions so two workers never publish the same item.

    Get it Docker or your package manager. open ↗

    Verify psql connects and creates a table

  3. free, and the review takes time

    Why The publishing and research APIs require a professional account type and app permissions the platform reviews, and a personal account cannot use them at all.

    Get it Convert or create the account type the developer documentation names, create an app, and request the permissions it lists; the hashtag endpoint needs a separate feature approval. open ↗

    Verify A test publish through the API succeeds on the account

  4. have readyfree

    Why Caption lengths, hashtag counts, image formats, carousel size, the publishing rate and the hashtag quota are all published and all change, and they live here as data.

    Get it Read the content publishing and hashtag search documentation and copy the current numbers into the limits file with today's date.

    Verify The limits file has a checked date and a source for every value

  5. have readypennies per month

    Why If your platform's publishing API fetches media from an address rather than accepting an upload, local files need a temporary public one.

    Get it Object storage with signed expiring links, or a small host with tokens; skip it if the API accepts uploads.

    Verify A link works for the stated period and then stops

  6. have readyfree

    Why The only honest hashtag performance data is your own, and the metrics phase needs real posts to fetch against.

    Get it Import them from the platform's data export or paste their links into the queue as already posted.

    Verify Fifty posted items exist with links

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- drafts(id, idea, body, media_ids_json, created_at, updated_at)
- variants(id, draft_id, platform, caption, hashtags_json, media_order_json, limits_version)
- platform_limits(platform, version, caption_max, hashtag_max, image_formats_json, carousel_max, checked_on, source_url) · data, not code
- queue_items(id, variant_id, publish_at, mode, state, published_id, attempts, last_error) · mode is by_hand or api
- publish_attempts(id, queue_item_id, at, container_id, result, error_json) · so a retry can check before posting again
- hashtag_lookups(id, hashtag, platform, looked_up_at, hashtag_id, result_json) · counted against the weekly quota
- metrics_snapshots(id, published_id, platform, fetched_at, values_json) · every figure carries the time it was fetched
- A queue item is by_hand or api, and the by_hand path is complete on its own, so the tool is useful before any platform has approved anything.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DATABASE_URLsecretrequiredpostgres://localhost:5432/plannerDrafts, queue, attempts, lookups and snapshots.
PLATFORM_APP_IDoptionalan app id from the developer consoleOnly for API publishing. The by-hand queue works without it.
PLATFORM_APP_SECRETsecretoptionalapp-secret-...redactedOnly for API publishing. Never logged.
LIMITS_PATHrequired./config/platform-limits.jsonDated limits per platform. A data edit, not a deploy.
HASHTAG_QUOTA_PER_WINDOWrequired30Copied from the published limit with its date. Recheck before changing.
HASHTAG_QUOTA_WINDOW_DAYSrequired7The window the quota applies to. Lookups are counted against it.
MEDIA_LINK_TTL_MINUTESoptional60Only where the API fetches from a URL. The link stops working after this.
SCRAPE_OR_DRIVE_BROWSERrequiredneverPresent as a constant. There is no other value that keeps the account.

The build, in order

  1. Drafts and platform variants as data

    One idea becomes per-platform versions checked against limits that are stored, dated and changeable.

    1. Caption, hashtags, formats, carousel size, checked date, source.

      Files config/platform-limits.jsonsrc/limits.ts

    2. With the limit and when it was checked.

      Files src/editor/validate.ts

    3. What the platform will show is what matters.

      Files src/editor/preview.ts

    done when · tick each as it passes
    watch out
    • Hard-coding a caption length or a carousel size means the tool is silently wrong the day the platform changes it, and the failure appears as a rejected post at publish time rather than in the editor. Store limits as data with the date they were checked, show that date, and make updating one a data change.
  2. A queue that needs no API

    Posting by hand is fast enough that the tool is useful with zero platform access.

    1. Copy, media, open, paste link, done.

      Files src/queue/byhand.ts

    2. A reminder an hour off is a post that misses its slot.

      Files src/queue/reminders.ts

    3. So the plan is visible where the person already looks.

      Files src/queue/ics.ts

    done when · tick each as it passes
    watch out
    • Building the API integration first means the tool does nothing until an app review completes, which can take weeks and may not succeed for a personal account. Build the by-hand path first and make it complete, since it works for every network.
  3. Publishing through the official API, once

    An eligible account publishes on schedule and a retry never posts twice.

    1. So a retry can check instead of guess.

      Files src/publish/worker.tssrc/publish/attempts.ts

    2. Injected timeout after publish, one post.

      Files tests/publish-retry.test.ts

    3. The limit is published, and the endpoint reports where you are against it.

      Files src/publish/limits.ts

    done when · tick each as it passes
    watch out
    • Retrying a publish call that timed out after the platform had already posted creates a duplicate the account owner sees before you do. Record the container id before publishing, and on retry query its status rather than publishing again. For the platform built here the published limit is a hundred API-published posts in a moving twenty-four hours, and the usage endpoint exists to be read before scheduling.
  4. Hashtag research inside the quota

    Research uses the official endpoint, spends its small weekly budget deliberately, and learns from your own posts.

    1. Thirty unique in seven days is the budget, and the cache stretches it.

      Files src/research/quota.tssrc/research/quota.test.ts

    2. A refusal here beats an error at the platform.

      Files src/research/search.ts

    3. Real metrics on your own hashtags, not a guess about anyone else's.

      Files src/research/own.ts

    done when · tick each as it passes
    watch out
    • Building research on scraped hashtag pages or an unofficial endpoint breaks the platform's terms and puts the account at risk, and the alternative of burning the weekly quota on the first day leaves nothing for the rest of the week. Count every lookup, cache, and show the budget.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more social media.