Recent Changes
This project is developed with AI assistance. Each feature shows the AI/Human contribution ratio:
- Decisions: Who drove the design choices (e.g., 30/70 = 30% AI, 70% Human)
- Code: Who wrote the implementation (e.g., 90/10 = 90% AI, 10% Human)
July 2026
Clear Out Participants Who Never Voted
On the admin results section, a "Delete N participants without votes" button now appears when anyone has opened the poll (or entered a name) without picking dates. One confirm clears them all — people who did vote stay put.
Decisions: 20/80 · Code: 95/5 · App size: +80 lines
Finalize Button Stays Greyed Out Until You Pick a Date
On the admin results table, the "Finalize" button is now visibly disabled until you select one of the date radios — previously it looked clickable and only complained with a browser popup when you actually clicked it without choosing.
Decisions: 30/70 · Code: 95/5 · App size: +30 lines
Clearer Error Feedback When Something Fails to Save
When an action can't be saved, you now get a small "Something went wrong — please try again" toast — previously most server-side failures showed nothing at all (only network drop-outs did). And a title/name that's too short now shows just its inline validation message, instead of also popping the generic error toast on top.
Decisions: 40/60 · Code: 90/10 · App size: +30 lines
Results Update Instantly When You Add or Remove a Date
On the admin page, adding or removing a candidate date now refreshes the Results/Finalize block right away — previously its list of finalizable dates lagged behind the calendar until you reloaded the page.
Decisions: 20/80 · Code: 95/5 · App size: +20 lines
See Who Hasn't Answered Yet
Participants who haven't offered a single date are now marked "no answer yet" under their name, instead of just showing an empty row you had to scan across — so it's obvious at a glance who still needs chasing. Someone who answered and then cleared all their dates counts as no answer too, rather than showing a misleading "voted" time.
Decisions: 20/80 · Code: 90/10 · App size: +15 lines
See When Each Participant Voted
The results now show a "voted <date, time>" line under each participant's name, so organisers can see when people last updated their availability. (Responses from before this change simply don't show a time.)
Decisions: 30/70 · Code: 90/10 · App size: +40 lines
Un-voting a Date the Organiser Later Removed
If an organiser removes a candidate date after people have already voted on it, voters can now remove their leftover vote for that date instead of hitting an "Invalid date selection" error. They still can't re-add it — a removed date is no longer offered — so the cell just becomes unavailable once un-voted.
Decisions: 30/70 · Code: 95/5 · App size: +15 lines
Polls Start With a Fun Auto-Generated Name
New polls now open with a random, playful two-word name like "Crazy Camping" instead of a blank field — so you can jump straight to picking dates without being forced to name it first. Rename it to something meaningful any time; the name just can't be left blank.
Decisions: 40/60 · Code: 90/10 · App size: +60 lines
List View No Longer Scrolls the Whole Page Sideways
On the list (matrix) view, a poll with lots of dates now scrolls sideways inside the table only — previously, reaching the end of the table dragged the entire page sideways, pushing the heading and tabs off-screen. Affects both the participant list view and the admin results table.
Decisions: 20/80 · Code: 95/5 · App size: +7 lines
Clearer Month Navigation Buttons
The previous/next month arrows on the calendar are now filled green and a touch larger, so it's obvious they're buttons you can tap to move between months. The 3-month skip arrows stay quiet alongside them.
Decisions: 30/70 · Code: 95/5 · App size: +17 lines
Vote Counts on Every Day of the Admin Calendar
The admin calendar now shows an "X of N" tally under every day, not just the ones you've enabled — so you can see at a glance how a date would stack up before adding it. It also fixes a glitch where a date you'd just toggled temporarily lost its count until the page was reloaded.
Decisions: 20/80 · Code: 90/10 · App size: +10 lines
Removed the Green Flash After Picking a Date
Dropped the green frame that briefly animated around a date after it was toggled. Now that a tap flips the date instantly and a "Saved" confirmation appears, the extra flash was redundant — the calendar feels calmer without it.
Decisions: 40/60 · Code: 95/5 · App size: -18 lines
Tapping a Date Feels Instant
Selecting a date on the calendar now flips immediately when you tap it, instead of waiting for the save to travel to the server and back (noticeable on mobile). Your choice appears at once and the save happens in the background. If a save actually fails — you're offline, or the poll just closed — the date quietly reverts to its real state and a small "Not saved" message appears, so you're never left thinking a vote registered when it didn't.
Decisions: 30/70 · Code: 85/15 · App size: +100 lines
Fewer False "Too Many Requests" Errors
Loosened the rate limits so normal use — picking lots of dates, flipping between months — no longer risks tripping the abuse protection. The stricter limits on sending emails and creating polls (the actual abuse vectors) stay in place.
Decisions: 20/80 · Code: 95/5 · App size: ~0 lines
Response Count No Longer Sticks at Zero
When you answer a poll, the "responses" count under the title now updates the moment you save your name — previously it kept showing "0 responses" until you reloaded the page, even though you'd already been counted. Reported by Tollef Fog Heen.
Decisions: 20/80 · Code: 95/5 · App size: +15 lines
Smoother Page Updates (HTMX 4)
Upgraded the interactivity engine and adopted a few of its new capabilities. Switching between the Calendar and List views now cross-fades instead of blinking. When you toggle a vote, only the cells that actually changed are patched in — your scroll position and the field you were typing in stay put, rather than the whole grid being rebuilt. Month navigation updates the same way. These are subtle-by-design: everything just feels a little less flickery.
Decisions: 40/60 · Code: 90/10 · App size: ~0 lines (mostly attribute changes)
Smoother "Saving" Feedback
The auto-save indicator now reads a plain "Saving" and fades in and out instead of snapping on with a static "Saving…". Very fast saves barely register — the box no longer flashes a hard edge — while slower saves on mobile ease in gently. The calendar indicator now behaves exactly like the one on the name/title fields.
Decisions: 30/70 · Code: 95/5 · App size: +5 lines
Calendar Always Opens on the Right Month
Returning to a poll now always opens the calendar on the most relevant month: where the votes are (for poll creators), where you voted (for participants), or where the candidate dates start — computed fresh every visit instead of replaying a month baked into an old bookmark. Month navigation now also updates the address bar, so the month you navigated to survives a reload and can be shared — and a shared link with a month in it always opens exactly that month.
Decisions: 50/50 · Code: 90/10 · App size: +60 lines
Consistent "Finalized" Callout Everywhere
The chosen-date display now looks the same in all three places a finalized poll shows up: the admin's own view, an existing participant's page, and the "poll closed" page a first-time visitor sees. Previously each rendered the finalized date differently (a plain admin banner, a compact callout, and a big celebratory card). They all now use the same green "🎉 Finalized" callout with the date and how many people were available. The closed page keeps its "no longer accepting new participants" note and the participant list (and no longer prints an empty "Participants: , ," when names are missing).
Decisions: 40/60 · Code: 90/10 · App size: -60 lines (refactor)
Removed the Availability Legend on the Voting Page
Dropped the small "✓ Available / ○ Not available" legend below the date picker. It appeared in both the Calendar and List views, but the ○ symbol only exists in the List matrix — in the Calendar it pointed at nothing, and the green selected days are clear on their own. Less clutter, same clarity.
Decisions: 20/80 · Code: 95/5 · App size: -30 lines
Vote Counts on the Admin Calendar
The admin's own calendar now shows how many people voted for each date right on the day cells — the same "N of M" bar and green highlight for the leading date that participants already see — so you can gauge the front-runner at a glance without scrolling down to the results table.
Decisions: 20/80 · Code: 90/10 · App size: +15 lines
Fix: Consistent Participant Counts
The response count in the poll header could disagree with the counts shown elsewhere — e.g. the header said "6 responses" while the finalized callout and list view both said "4 people". The header was counting every visit that opened the poll, including people who never entered a name. Now every count — header, callout, list view, and the calendar's per-date totals — counts the same thing: people who've actually entered a name.
Decisions: 10/90 · Code: 90/10 · App size: +10 lines
Admin Page Flow Cleanup + Richer Poll Header
Reworked the admin page into a deliberate order instead of sections piled on over time. The biggest change: once people start voting, the results table jumps up right under the calendar — where you'll look first when you come back — instead of sitting below the share and email sections. Before anyone has voted, it stays lower (there's nothing to see yet). The "add your email so you don't lose this poll" prompt moved up next to the share section, and the "Open on phone" QR moved below the results. The poll header now also shows how many dates you've put up and a small Active/Finalized badge, alongside the organiser and response count.
Decisions: 30/70 · Code: 90/10 · App size: +40 lines
Participant Page Flow Cleanup + Finalized Callout
Reworked the participant voting page into a deliberate top-to-bottom order instead of sections bolted on over time. While a poll is active: your name, a bookmark reminder, the date picker, your email, then next-steps + share — in that order. Once a poll is finalized, the page now leads with a clear "🎉 Finalized" callout showing the chosen date and how many people were available, and defaults to the List view (the who-voted-for-what matrix, more useful for reviewing a decided outcome). Even someone opening a finalized poll link for the first time now sees the outcome and the results. The "who's winning" front-runner callout no longer appears while voting is still open — it only made sense once a date is actually chosen. The post-voting "Copy Link" now uses the exact same share behaviour as the header's Share button (one shared component instead of two near-identical copies).
Decisions: 30/70 · Code: 90/10 · App size: +20 lines
Fix: Email Verification Failures Are No Longer Silent
Found and fixed a real bug: if the email provider failed to send a verification email (invalid API key, unverified sending domain, rate limit, etc.), the app previously logged "sent" and told you to check your inbox regardless — the failure was silently discarded. Now a failure is properly reported: you'll see an error message telling you to try again, instead of waiting for an email that was never sent.
Decisions: 10/90 · Code: 90/10 · App size: +15 lines
Token Legend + Auto-save Note Below the Calendar/List View
A small legend ("✓ Available ○ Not available") now appears below the calendar or list view on the participant page, explaining what the checkmark and circle symbols mean. Right below it, a persistent "Saved automatically as you go" note confirms your changes are saved without you needing to find a submit button. Both hidden once a poll is finalized.
Decisions: 20/80 · Code: 90/10 · App size: +35 lines
Poll Header Meta Row
Both the admin and participant pages now show a respondent count under the poll title (e.g. "3 responses"), and admins additionally see who's organising the poll. Your email is never shown on the public participant page, even if you're the organiser — that page can be reached by anyone with the share link.
Decisions: 20/80 · Code: 90/10 · App size: +50 lines
Topbar Share Button
A "Share" button is now always visible in the page header on both admin and participant pages, so you don't have to scroll down to the share card to grab the poll link. Uses your phone's native share menu when available, otherwise copies the link with "Copied!" feedback. Always shares the safe participant link, never the admin link, and stays visible even after a poll is finalized. The existing "Share with participants" card and post-voting share link are unchanged — they're still there for first-time discovery.
Decisions: 20/80 · Code: 90/10 · App size: +70 lines
List View Polish: Shared Panel, Stable Highlighting, Layout Fixes
Follow-up fixes to the Calendar/List switcher: the switcher and whichever view is active now share one bordered panel with a single "Saved" toast, instead of each view drawing its own. Fixed a bug where the highlighted "most votes" column could get out of sync after a toggle by re-rendering the whole matrix on each vote. Fixed a stray empty box that appeared under the Calendar/List tabs, and a column-width jump that happened when a date's vote count changed — both traced back to browser quirks (an absolutely-positioned toast losing its containing box, and native <button> sizing quirks in a flex layout).
Decisions: 20/80 · Code: 90/10 · App size: +40 lines
List View: Vote Directly from the Availability Matrix
The participant page now has a Calendar/List switcher. List view shows the full participant × date matrix and lets you vote by clicking your own row's cells — no more switching back to the calendar to change your vote. Your choice is remembered in the URL, so a bookmarked or shared link opens straight into whichever view you were using.
Decisions: 30/70 · Code: 90/10 · App size: +250 lines
Gravatar Avatars
Your account icon and participant rows in the results table now show your real Gravatar photo if you have one registered, instead of always showing a generic icon or colored initials. If you don't have a Gravatar, nothing changes — you still see the existing icon/initials as before.
Decisions: 30/70 · Code: 90/10 · App size: +50 lines
Dependency Upgrades & Rate Limit Bug Fix
Routine dependency upgrades across the stack (Ktor, Kotlin, Exposed, Flyway, Selenium, and others). Along the way we found and fixed a real bug: requests that hit the rate limiter were returning a raw 500 error instead of the intended 429 "too many requests" response, caused by a plugin ordering issue introduced by the Ktor upgrade.
Decisions: 10/90 · Code: 90/10 · App size: ~0 lines
Delete Participant Directly from the Results Matrix
Admins can now remove a participant right from their row in the results matrix, instead of scrolling to a separate list below it.
Decisions: 20/80 · Code: 90/10 · App size: +15 lines
More Visible Calendar Navigation
The month navigation buttons (« ‹ › ») were nearly invisible (white on white). They now have a light fill and darker border/icon so they're easy to spot, and the "Saved" confirmation now appears centered between the buttons instead of leaving an empty gap below them.
Decisions: 30/70 · Code: 90/10 · App size: +10 lines
Bottom Calendar Navigation
Long months no longer require scrolling back to the top to change month — the ‹ prev / next › (and skip) buttons now repeat at the bottom of the calendar card too.
Decisions: 20/80 · Code: 95/5 · App size: +30 lines
Who's Available Grid on the Participant Page
Participants now see a real matrix of everyone's answers (participant × date, with a "You" row) instead of a plain list of names. Voting still happens via the calendar for now — the grid is a read-only view of the group's availability.
Decisions: 40/60 · Code: 90/10 · App size: +140 lines
April 2026
Cleaner Finalized Poll View
When a poll is finalized, the admin page is now more focused:
- Results table is shown directly inside the "Poll Finalized" box
- Admin URL sharing notice is hidden (no longer needed)
- Less clutter — just the result and the calendar
Decisions: 20/80 · Code: 95/5 · App size: +20 lines
Most-Voted Dates Highlighted
Before finalizing, date columns with the most votes are now highlighted in the results table, making it easier to pick the best date.
Decisions: 30/70 · Code: 90/10 · App size: +30 lines
January 2026
Improved Help & Navigation
Several small improvements to help users find their way around:
- Login link added to landing page info box for easier access
- URL notices on admin and participant pages now mention "My Polls" as the way to find your polls later
- Participants see a reminder to verify their email for easier return visits
- Consolidated CSS for faster page loads
Decisions: 20/80 · Code: 90/10 · App size: +50 lines
Faster Startup & Better Monitoring
Infrastructure improvements for better performance and observability:
- Switched to New Relic for application monitoring
- Reduced startup time with optimized database connection pooling
- Smaller Docker image using Alpine JRE
- Parallel test execution for faster CI builds
- LightningCSS binary caching in CI
Decisions: 30/70 · Code: 85/15 · App size: +100 lines
December 2025
Log In Link for Visitors
Non-authenticated users now see a "Log in" link in the header. Clicking it takes you to a login page where you can verify your email to access your polls. For now, email is the only login method available.
Decisions: 20/80 · Code: 95/5 · App size: +50 lines
Account Icon with Log Out
Signed-in users now see a person icon in the header. Click it to see your email and a "Log out" link. Logging out clears your session and redirects you to the home page.
Decisions: 20/80 · Code: 95/5 · App size: +150 lines
My Polls: Both Admin and Participant Links
When you're both the creator and a participant of a poll, the My Polls page now shows links to both views. The main poll card links to the admin page as before, and a new "My Response" link in the corner takes you directly to your participant response. No more hunting for the right URL!
Decisions: 20/80 · Code: 95/5 · App size: +40 lines
Fourth Step in Admin Workflow
The admin progress indicator now includes a fourth step: "4. Finalize". This step becomes active when participants have voted, guiding you to choose a final date once everyone has responded. Completed when you finalize the poll.
Decisions: 30/70 · Code: 95/5 · App size: +30 lines
Delete Poll from Admin Page
You can now delete a poll directly from its admin page. A red "Delete Poll" button at the bottom of the page opens a confirmation dialog before deleting. After deletion, you're redirected to your My Polls list.
Decisions: 20/80 · Code: 90/10 · App size: +25 lines
Keyboard Shortcuts for Delete Confirmation
The delete confirmation dialog now responds to keyboard shortcuts: press Escape to cancel or Enter to confirm. Makes the delete workflow faster for keyboard users.
Decisions: 5/95 · Code: 95/5 · App size: +5 lines
Calendar Toast Visibility Fix
Fixed an issue where the "Saved" toast notification was being clipped by the calendar border. The toast now appears below the calendar where it's fully visible.
Decisions: 10/90 · Code: 95/5 · App size: +5 lines
Accessibility Improvements
Improved accessibility across all pages based on Lighthouse audit findings. Color contrast now meets WCAG standards (using darker shades for text), heading hierarchy follows proper order (h1 → h2 → h3), and all form inputs have proper labels for screen readers. Calendar day buttons now have aria-labels describing each date.
Decisions: 10/90 · Code: 95/5 · App size: +20 lines
Calendar Month Stays Put
Fixed an annoying bug where the calendar would jump back to the current month whenever you saved your name or the poll title. Now the calendar stays on whichever month you were viewing, so you can browse future months without interruption.
Decisions: 5/95 · Code: 95/5 · App size: +10 lines
Step Indicator Dynamic Updates
The admin progress steps now update in real-time as you make changes. Previously, the step indicator only showed the correct state on page load. Now when you add a title or select dates, the steps immediately reflect your progress without needing to refresh.
Decisions: 10/90 · Code: 90/10 · App size: +15 lines
Lazy Device Creation
Cookies are now only set when you actually interact with greitt (create a poll or vote). Just browsing the landing page or viewing polls won't store anything on your device. Better privacy by default.
Decisions: 20/80 · Code: 90/10 · App size: +30 lines
Static Asset Caching
Images, CSS, and JavaScript files are now cached in your browser for 1 hour. Pages load faster on repeat visits.
Decisions: 10/90 · Code: 95/5 · App size: +10 lines
Visual Progress Steps
The admin page now shows your progress with color-coded steps: "1. Name your poll → 2. Pick dates → 3. Share". Completed steps turn green with a checkmark, the current step is highlighted, and pending steps are grayed out. As you work through setting up your poll, the indicator updates automatically to show what's done and what's next.
Decisions: 30/70 · Code: 85/15 · App size: +75 lines
Enter Key Support for Text Fields
You can now press Enter to save changes in text input fields (poll title and participant name). No need to click the Save button - just type and press Enter for faster workflow.
Decisions: 5/95 · Code: 95/5 · App size: +15 lines
Calendar Overlay UX Improvement
When the calendar is disabled (before entering poll title or participant name), the overlay message now appears on top of the calendar instead of pushing it down. This prevents jarring layout shifts and makes the disabled state clearer. The overlay text is also bolder for better readability.
Decisions: 15/85 · Code: 95/5 · App size: +10 lines
My Polls Email Verification Box
Users visiting the My Polls page without verification can now enter their email directly on the page. A clear verification box appears with instructions, making it easier to access your polls without navigating away.
Decisions: 10/90 · Code: 95/5 · App size: +25 lines
Name Your Poll First
New polls now start with an empty title instead of "New Poll". Before you can pick dates, you need to give your poll a name. The calendar shows a friendly prompt until you enter a title. This helps ensure your shared links have meaningful names that participants will recognize.
Decisions: 20/80 · Code: 90/10 · App size: +30 lines
Native Mobile Sharing
You can now share polls directly to messaging apps on mobile devices. When viewing a poll (as admin or participant), there's a new "Share" button that opens your phone's native share menu - letting you send the poll link via WhatsApp, Telegram, iMessage, email, or any other app. On desktop browsers without native sharing, the Share button is hidden and you continue using the Copy Link button. This makes it faster to invite participants on mobile.
Decisions: 10/90 · Code: 95/5 · App size: +60 lines
Clearer Post-Voting Instructions
After voting, participants now see clearer instructions about what happens next. The "What happens next?" section explains that the poll creator will review everyone's availability and let you know when a date is decided. This reduces uncertainty about the next steps in the process.
Decisions: 20/80 · Code: 95/5 · App size: +5 lines
Cleaner Name Input After Save
After you enter your name on the participant page, the Save Name button disappears. The name input stays visible so you can edit it later - changes auto-save when you click away or press Enter. This reduces visual clutter and makes it clearer that your name was saved.
Decisions: 5/95 · Code: 100/0 · App size: +10 lines
My Polls Card Layout
Poll cards on the My Polls page now have consistent widths. The delete icon is positioned inside the card (top-right corner) rather than in a separate column. This means non-admin poll cards look the same as admin cards.
Decisions: 10/90 · Code: 95/5 · App size: +5 lines
Robots.txt and Privacy Protection
Poll URLs are now protected from search engine indexing. The robots.txt file blocks all poll-specific paths, and poll pages include a noindex meta tag. AI training bots (GPTBot, CCBot, Claude, etc.) are blocked entirely to protect user data.
Decisions: 10/90 · Code: 95/5 · App size: +50 lines
Improved Form Styling
The Save Name button on the participant page is now full-width to match the input field above it, creating better visual alignment. Buttons that follow input fields now have proper spacing for a cleaner form appearance.
Decisions: 10/90 · Code: 95/5 · App size: +10 lines
Browse Dates Before Entering Name
Participants now see the calendar immediately when opening a poll link. You can browse all available dates before entering your name. The calendar is read-only until you provide your name, then you can click dates to vote. This lets you quickly see if any dates work before committing.
Decisions: 10/90 · Code: 95/5 · App size: +40 lines
Cleaner Admin Page Share Section
The admin page now has a cleaner share section that combines the admin notice with the share link. Instead of a separate warning banner, there's now a subtle warning below the share link: "Your current URL is the admin link — don't share it unless you want others to edit this poll." This reduces clutter while keeping the important distinction clear.
Decisions: 10/90 · Code: 90/10 · App size: -10 lines (removed separate admin notice)
Participant Cards in Admin Results
Participant responses on the admin page now display in styled cards with light gray backgrounds, subtle borders, and rounded corners. This provides better visual separation between participants and matches the card styling used on the My Polls page.
Decisions: 10/90 · Code: 95/5 · App size: +30 lines
Week Numbers in Calendar
The calendar now shows ISO week numbers on the left side. A "Wk" header appears above the week column, and each row shows the week number (1-53). This helps with "week 47" style scheduling common in European business contexts.
Decisions: 10/90 · Code: 95/5 · App size: +50 lines
Date Selection Shortcuts
Admins can now quickly select all weekdays, weekends, or all days in a month with one click. Shortcut buttons appear below the calendar grid with a "Select:" label. Clicking a shortcut toggles those dates - click again to deselect. Great for setting up recurring meetings!
Decisions: 30/70 · Code: 85/15 · App size: +80 lines
Share Button for Participants
Participants can now share the poll link with others directly from the calendar page. A "Share This Poll" section appears below the calendar with a copy-to-clipboard button. Share away!
Decisions: 10/90 · Code: 95/5 · App size: +20 lines (refactored to reuse admin share code)
Clickable Logo
The greitt logo in the header now links back to the home page.
Decisions: 0/100 · Code: 100/0 · App size: +5 lines
Landing Page
The home page now shows an informative landing page instead of immediately creating a poll. You'll see a brief explanation of what greitt does and a prominent "Create Poll" button. This reduces accidental poll creation and gives new users a better first impression.
Decisions: 20/80 · Code: 85/15 · App size: +40 lines
Shorter Share URLs
Poll share links are now shorter and cleaner. Instead of long UUID-based URLs, share links now use compact nanoid identifiers (e.g., /s/b0dP92eUH1cW). The short URL redirects to the full poll page.
Decisions: 30/70 · Code: 90/10 · App size: +60 lines
Remove Participant
Admins can now remove participants from a poll. A trash icon appears next to each participant in the results section. Clicking it shows a confirmation modal before removing the participant.
Decisions: 20/80 · Code: 95/5 · App size: +50 lines
Improved Delete Confirmation
Poll deletion now uses a custom styled modal instead of the browser's default confirmation dialog. The modal provides a cleaner experience with clear Cancel/Delete buttons.
Decisions: 20/80 · Code: 90/10 · App size: +100 lines
Multiple Admin Emails
Polls can now have multiple admin email addresses. Additional admins automatically receive notification when a verified user accesses the admin page.
Decisions: 30/70 · Code: 85/15 · App size: +80 lines
Autosave Feedback
When you make changes, you now get visual confirmation:
- Calendar dates: Green outline animation and "Saved" toast when clicking dates
- Text fields: "Saved" indicator appears after editing title and other inputs
These visual cues confirm your changes were recorded without interrupting your workflow.
Decisions: 30/70 · Code: 80/20 · App size: +50 lines
Changes Page
View recent changes at /changes - this page! Markdown rendered to HTML using commonmark.
Decisions: 50/50 · Code: 90/10 · App size: +80 lines
Inactive Poll Expiration
Polls now automatically expire based on inactivity to keep the database clean:
- Polls without admin email: Expire after 30 days of inactivity
- Polls with admin email or finalized: Expire after 90 days of inactivity
Any activity (title changes, date selections, new votes) resets the clock.
Decisions: 20/80 · Code: 85/15 · App size: +200 lines
My Polls Improvements
- Dual role icons: Shows both crown (admin) and person (participant) when you have both roles on a poll
- Finalized indicator: Completed polls now show a green "Finalized" badge
- Smart redirects: Verified users are automatically redirected to their existing response instead of creating duplicates
Decisions: 30/70 · Code: 80/20 · App size: +100 lines
Participant Email Verification
- Participants can optionally verify their email to easily return and edit responses
- Verified users get their email auto-populated when joining new polls
- Same verification system used for both admin and participant features
Decisions: 25/75 · Code: 75/25 · App size: +150 lines
Abandoned Poll Cleanup
Polls that were created but never configured (no dates selected) are automatically deleted after 24 hours.
Decisions: 40/60 · Code: 90/10 · App size: +80 lines
Modern UI Design System
- Unified green theme across all components
- Complete design token system with CSS variables
- Improved card styling, buttons, and form inputs
- Updated logo to match the green theme
Decisions: 30/70 · Code: 70/30 · App size: +200 lines
Device-Based Authentication
Your device is now automatically recognized when you return to greitt. No need to enter your email every time - your polls and responses are linked to your browser. You can still verify your email to access your polls from other devices.
Decisions: 30/70 · Code: 85/15 · App size: +300 lines
Toast Notifications
Visual feedback when actions complete: a brief "Saved" message slides in and fades out after saving poll titles, names, or date selections. Helps confirm your changes without interrupting your workflow.
Decisions: 20/80 · Code: 90/10 · App size: +60 lines
June 2025
Modern Design Overhaul
Complete visual redesign with a new logo, modern styling, and cohesive color scheme. Admin and participant pages received updated layouts with improved card designs and better visual hierarchy.
Decisions: 30/70 · Code: 70/30 · App size: +400 lines
PostCSS Integration
Added runtime CSS processing using GraalJS and Webpack. CSS is now processed with PostCSS plugins for better browser compatibility and smaller file sizes. Later replaced with LightningCSS for better performance.
Decisions: 40/60 · Code: 80/20 · App size: +300 lines
Copy URL Button
Added a "Copy Link" button next to the share URL input field, making it easy to copy poll links to your clipboard with one click.
Decisions: 10/90 · Code: 95/5 · App size: +20 lines
Real-Time Title Updates
Poll titles now update in real-time using HTMX. As you type, the title is saved automatically without needing to click a button or refresh the page.
Decisions: 20/80 · Code: 85/15 · App size: +50 lines
Share Link for Participants
Participants can now see and share the poll link directly from the calendar page. A dedicated section shows the shareable URL with a copy button.
Decisions: 10/90 · Code: 90/10 · App size: +30 lines
Calendar Component Refactoring
The calendar rendering logic was restructured into separate, focused components. This improves code maintainability and makes it easier to add new calendar features.
Decisions: 50/50 · Code: 85/15 · App size: ~0 lines (refactor)
May 2025
Participant Date Selection Limit
Participants can now only select from dates that the admin has marked as available. The calendar clearly shows which dates are selectable and which are not.
Decisions: 20/80 · Code: 90/10 · App size: +40 lines
Admin Date Marking
Admins can click calendar dates to mark them as available for the poll. Selected dates are visually highlighted so you can see your selection at a glance.
Decisions: 20/80 · Code: 85/15 · App size: +60 lines
Controllable Clock for Testing
Tests now use a controllable clock, enabling reliable date-based testing without depending on the current system time.
Decisions: 40/60 · Code: 90/10 · App size: +80 lines
January 2025
Initial Release
greitt launches with core scheduling functionality:
- Create polls with selectable date ranges
- Share polls via unique URLs
- Participants vote on available dates
- Admin view shows all responses
- HTMX-powered real-time updates
- Kotlin/Ktor backend with PostgreSQL storage
- Selenium-based E2E testing
Decisions: 60/40 · Code: 60/40 · App size: ~3000 lines