Alpkit Alpkit Custom DevIn-house tools & integrations

foundation-awards-base

Manages the entire Alpkit Foundation grant application process, helping staff handle hundreds of applications efficiently without relying on spreadsheets or manual emails. It organizes applications as easy-to-read files, collects trustee votes in shared spreadsheets, and automates sending outcome emails, making grant decisions smoother and less error-prone. This system is ideal for grant administrators who need to coordinate reviews and communicate results reliably.

Operations & monitoring · Updated 4 Jun 2026 · View on GitHub (requires access)

AKF Applications — System Overview

End-to-end pipeline for Alpkit Foundation grant applications. Replaces a manual Microsoft Forms + spreadsheet process that became unsustainable as volume grew to 300–600 applications per batch, every two months.


Why it works this way

Applications as Markdown files. Each application is a single .md file with YAML frontmatter. No database to set up or maintain, no schema migrations, no JOIN queries. The narrative sections (description, case statement) live in the same file as the structured data. Readable in any text editor and works naturally with version control.

Trustees vote in a shared spreadsheet. One XLS per group is uploaded to SharePoint. Trustees mark their votes directly — no file to email back, no returns to collect. On awards night the spreadsheet is sorted by vote count and fed straight into decide.py.

Decisions are decoupled from emails. After the meeting, applications sit at approved-pending-email or declined-pending-email until you're ready to send. This gives a dry-run window before anything goes out.

Shortlisting rule: any one vote. An application only needs a single trustee champion to reach the meeting. A majority-required rule would risk strong-but-unusual applications being dropped before anyone could discuss them.

Technology-assisted prioritisation. A rule-based system applies the AKF Prioritisation Criteria to rank applications before the trustee meeting. Contact fields are excluded from the assessment to prevent identity-based bias. The system produces a consistent, repeatable ranked order — trustees review every application and make all funding decisions.

Email via Microsoft Graph. Outcome emails send from akf@alpkit.com using the existing M365 infrastructure. No third-party service subscription; consistent with the organisation's existing setup.


Tools

Tool Purpose
Tally Application form — conditional logic for eligibility gate, REST API for intake
Microsoft Graph API Sending outcome emails from akf@alpkit.com
Azure (AKF Email Sender app) App-only auth for Graph — no user login required at runtime
Python 3 All scripts — no deployment needed, runs on any machine
openpyxl Excel generation for trustee review sheets and shortlist
reportlab PDF generation for trustee meeting reference doc

Directory structure

021_AKF_Applications/
├── scripts/
│   ├── intake.py           Tally API → MD files
│   ├── score.py            Auto-score applications [to build]
│   ├── batch.py            Assign batch + group fields
│   ├── export_sheets.py    Excel review sheet per group → reviews/sheets/
│   ├── combine.py          Aggregate returned votes → shortlist
│   ├── preview_pdf.py      Trustee meeting PDF
│   ├── decide.py           Record decisions live at meeting
│   └── send_emails.py      Outcome emails via Microsoft Graph
├── applications/           All applications as MD files (one per submission)
│   └── Historic/           15,471 converted historic applications
├── reviews/
│   ├── sheets/             Generated trustee review spreadsheets
│   ├── returns/            Returned trustee spreadsheets (drop here)
│   └── templates/          Email templates (email_success.md, email_decline.md)
├── logs/                   Timestamped email send logs
├── archive/                Retired files
├── TEST-Applications/      10 test applications for script development
├── README.md               This document
├── DESIGN.md               System design, decisions, open questions, build status
├── Trustees_Guide.md       Operational guide for running a batch (steps 4–7)
├── AKF_Scoring_Rulebook.md Scoring methodology — also used as AI scoring prompt
├── tally.env               API credentials (not committed)
└── requirements.txt        Python dependencies

Scoring system

Applications are scored 0–5 across five dimensions:

Dimension What it checks
1. Outdoor activity Project is centred on a qualifying outdoor activity
2. Inclusion Applicant serves people who face identified barriers
3. Proportionate ask Request is specific, costed, and ≤ £5,000
4. Identified beneficiaries Names who benefits, in what number, and why they need support
5. Category fit Falls within Participation, Health, Education, Environment, or Diversity

Score-5 applications receive a sub-score (0–10) to rank the strongest within the top tier. If Dimension 1 = 0, the maximum overall score is 2 regardless of other dimensions.

Full methodology and edge case decisions: AKF_Scoring_Rulebook.md


Open decisions

# Decision Status
1 score.py — Claude API with prompt caching, contact fields stripped Agreed, not built
2 SharePoint upload — automate via Graph API after generating preview pack Parked — manual first cycle
3 Non-shortlisted applications — bulk decline after decide.py? Open
4 Award claim form (tally.so/r/9qvvpV) To build
5 Financial award payment — manual bank transfer or automated? Open
6 Equipment voucher generation — Shopify voucher API? Open
7 Follow-up timing — how long after project end before requesting report? Open

For setup, schema, status lifecycle, and build status: see LOG.md For running a batch end-to-end: see Trustees_Guide.md