Development Journal
"At some point the journal ceased to be a record of the development process and became one of its outputs."
Introduction
Exchange Opinions began as an attempt to answer a simple question:
How can public opinion be captured, aggregated and represented in a structured way without descending into the noise often associated with social media?
The platform combines elements of polling, dashboards, reporting, public participation and data visualisation to create a continuously evolving picture of opinion, understanding and interest across topics, services and locations.
This development blog records the major milestones and decisions made during development.
Entry 1 - Naming the Platform
Feature
Creation of the Exchange Opinions identity.
Decision
The name needed to describe both the purpose of the platform and the interaction taking place between participants. There were a few other suggestions mooted, some available, some not, however this one seemed more concrete and less abstract than some of those others.
Opinions are not merely collected.
They are exchanged.
Participants contribute views, consume insights and influence future discussions.
Philosophy
The platform is designed around participation rather than broadcasting.
Entry 2 - Branding and Visual Identity
Feature
Creation of logos, colours and branding.
Decision
The visual identity needed to appear:
- neutral
- trustworthy
- modern
- informative
rather than politically aligned or commercially aggressive.
Philosophy
The platform should present itself as an information service rather than an advocacy platform.
Entry 3 - User Authentication
Feature
User registration and login.
Technology
React front end
AWS Lambda
API Gateway
JWT authentication
Decision
Opinion submissions must be attributable to authenticated users while preserving privacy.
Philosophy
Trust begins with accountability.
Entry 4 - Topic Hierarchy
Feature
Structured topic categorisation.
Decision
Topics are grouped into logical categories to improve discoverability and reporting.
Philosophy
Information becomes more useful when it can be organised and compared consistently.
Early Concepts
Entry 5 - Geographic Hierarchy
Feature
Regional, Area and Local structures.
Decision
Users can submit opinions against multiple geographic levels.
Philosophy
National issues often have local impacts.
Local issues can reveal national patterns.
Entry 6 - Sentiment Framework
Feature
Introduction of structured sentiment categories.
Examples include:
- Concerned
- Interested
- Frustrated
- Confident
- Amazed
- Informed
- Uninformed
- Decision
Traditional positive/negative sentiment was considered insufficient.
Philosophy
Human opinion is multidimensional.
Understanding emotion is often as important as understanding agreement.
Entry 7 - Justifications
Feature
Supporting explanations for opinions.
Decision
Users may explain the reasoning behind their views.
Philosophy
Numbers tell us what people think.
Justifications help explain why.
Entry 8 - Opinion Lifecycle
Feature
Opinion expiry and renewal.
Decision
Opinions are not permanent.
Users must periodically renew them.
Philosophy
Public opinion changes.
The platform should reflect current views rather than preserve outdated assumptions indefinitely.
Architecture and Implementation
Entry 9 - Aggregation Engine
Feature
Automated rollups.
Technology
Serverless aggregation processes.
Decision
Opinions are aggregated at:
- Local
- Area
- Regional
levels.
Philosophy
The value of the platform lies not in individual opinions but in collective patterns.
Entry 10 - Event-Driven Processing
Feature
Asynchronous opinion processing and aggregation.
Technology
- AWS Lambda
- Amazon SQS
- DynamoDB
Decision
Opinion capture was separated from aggregation and reporting activities using message queues and serverless processing.
This allowed user interactions to remain responsive while heavier processing tasks were performed in the background.
Philosophy
Users should never have to wait for analytics.
Opinion capture and insight generation are related activities, but they do not need to occur simultaneously.
Costs are reduced if recalculated at point of entry, rather than requiring realtime reconstitution of the aggregate using full table scans.
Outcome
A scalable processing pipeline capable of supporting increasing participation volumes without redesigning the platform architecture.
Entry 11 - Data Model and Aggregation Storage
Feature
Hierarchical opinion storage and rollup architecture.
Technology
- DynamoDB
- Global Secondary Indexes
- Serverless aggregation
Decision
Rather than treating every opinion as an isolated record, the platform stores and aggregates information across multiple dimensions:
- Topic
- Geography
- Service
- Time
- Sentiment
This allows dashboards and reports to be generated rapidly without repeatedly recalculating large datasets.
Philosophy
The value of a dataset increases when relationships between records can be explored efficiently.
Entry 12 - Historical Data and Trend Analysis
Feature
Historical aggregation and time-based reporting.
Decision
The platform preserves aggregated historical information so that sentiment and participation can be compared across different periods.
Philosophy
A single snapshot tells us what people think today.
Historical analysis helps reveal:
- trends
- shifts in sentiment
- emerging issues
- declining concerns
Outcome
The foundation for longitudinal analysis and future trend reporting.
Visualisations
Entry 13 - Time Period Visualisation
Feature
Period-based dashboard views.
Components
- Last 7 Days
- Last 30 Days
- Last 90 Days
- Historical Views
Decision
Users should be able to understand not only the current state of opinion, but how it evolves over time.
Philosophy
Movement is often more interesting than position.
Changes in sentiment frequently reveal more than sentiment itself.
Entry 14 - Dashboard Navigation and Discovery
Feature
Interactive browsing components.
Components
- Geographic selectors
- Topic selectors
- Service selectors
- Drill-down navigation
- Search and discovery
Decision
Users should be able to navigate naturally between national, regional and local viewpoints.
Philosophy
Exploration often leads to insight.
Users should be encouraged to discover patterns rather than simply consume predefined reports.
Entry 15 - Sentiment Dashboard Framework
Feature
Unified dashboard architecture.
Components
- Sentiment cards
- Summary metrics
- Comparative views
- Participation indicators
Decision
Provide a consistent experience regardless of which dataset is being viewed.
Philosophy
Consistency reduces cognitive effort and encourages exploration.
Entry 16 - Topic Browser
Feature
Topic exploration interface.
Decision
Allow users to browse emerging and established topics through multiple routes rather than relying solely on search.
Philosophy
Important issues are not always the ones users initially seek.
Discovery should be supported alongside search.
Entry 17 - Service and Organisation Views
Feature
Service-centric reporting.
Decision
Enable opinions relating to services and organisations to be viewed independently from broader topics.
Philosophy
People often experience policy through services.
Understanding service sentiment provides a different perspective from understanding political sentiment.
Entry 18 - Word Clouds and Theme Extraction
Feature
Justification based word clouds to visualise frequently used keywords in user opinions, both on the topic and per opinion.
Technology
- Keyword extraction
- Frequency analysis
- Aggregated textual reporting
Philosophy
Structured sentiment explains how people feel.
Textual analysis helps explain why.
The combination of quantitative and qualitative information provides a richer picture than either approach alone.
Entry 19 - Sentiment Area Map
Feature
Geographic sentiment visualisation.
Decision
Display prevailing sentiment geographically across local areas.
Philosophy
Patterns are often easier to recognise spatially than numerically.
Outcome
One of the platform's most distinctive visualisations.
Reporting
Entry 20 - Reporting Framework
Feature
Formal report generation.
Decision
Create a bridge between dashboards and publishable outputs.
Philosophy
Insights become more valuable when they can be shared, archived and compared over time.
Entry 21 - Report Preview System
Feature
Public report previews.
Decision
Allow users to inspect report structure before purchasing.
Business Decision
Demonstrate value before requesting payment.
Entry 22 - Full Report Generation
Feature
Server-side report generation and storage.
Decision
Generate reusable report artefacts that can be accessed after purchase.
Philosophy
Reporting should be scalable and reproducible.
Entry 23 - Report Generation Architecture
Feature
Trusted aggregates and numbers
Technology
- Lambda-based report generation
- S3 storage
- On-demand document production
Decision
Reports are generated from the same underlying datasets used by the dashboards.
Philosophy
A single source of truth reduces inconsistency between visualisations and published reports.
Final Touches
Entry 24 - User Experience Refinement
Feature
Opinion submission redesign.
Components
- Simplified multi-step forms
- Breadcrumb navigation
- Reduced submission friction
- Contextual guidance
- Edit and review improvements
Decision
Lower the effort required to contribute opinions while maintaining data quality.
Philosophy
Participation is more likely when the process feels simple and approachable.
Entry 25 - Data Quality and Validation
Feature
Accurate and trustworthy aggregation numbers that add up and make sense across the various dashboards
Technology
- Additional Topics
- Aggregation reconciliation
- Rollup verification
- Historical consistency checks
- Dashboard/report alignment
Philosophy
Users must be able to trust that the same question produces the same answer regardless of where it is viewed.
Entry 26 - Deployment and Scalability
Feature
One of the questions raised during development was whether the platform could realistically be deployed beyond its initial Yorkshire and Humber trial area.
Rather than waiting until after launch to answer that question, we spent time reviewing how the platform could be configured, deployed and isolated across multiple environments and regions.
Technology
The platform now supports environment-aware deployment using a combination of:
- AWS Lambda
- DynamoDB
- SQS
- SES
Environment-specific configuration
Database tables, queues and functions are named using a consistent convention incorporating environment, country and region identifiers.
For example:
EO-DEV-ENG-YH EO-PROD-ENG-YH
This allows deployments to remain isolated whilst sharing the same application code.
- Deployment
- A deployment script was created to automate:
- Lambda packaging
- Lambda deployment
- IAM role creation
- Environment variable configuration
- DynamoDB permissions
- SQS permissions
- SES permissions
This significantly reduces the manual effort required to create and maintain environments.
Scalability
The objective was not to create dozens of deployments immediately, but to understand whether the architecture could support them.
By parameterising environments, countries and regions, the platform moves from:
One deployment
to:
One deployment model Many configurations
This provides flexibility for future expansion, whether through direct operation, regional rollout or potential licensing.
Observations
The most valuable outcome was not the creation of additional environments themselves, but the reduction of deployment effort and operational complexity.
Much of software development is not about solving a problem once. It is about understanding how many times the same problem may need to be solved in the future.
This work represents an investment in repeatability, maintainability and future growth, regardless of the eventual scale of the platform.
Commercialisation
Entry 27 - Monetisation Model
Feature
Introduction of paid reports and publication services.
Business Decision
Monetisation must not influence sentiment outcomes.
Philosophy
The integrity of the dataset is more important than short-term revenue.
Users cannot purchase influence over aggregated opinion.
Entry 28 - Minimal Advertising Strategy
Feature
Advertising framework.
Decision
Limit advertising exposure.
Philosophy
The platform seeks to capture attention for insight, not extract attention for profit.
Entry 29 - Pricing and Monetisation Framework
Feature
Establish a simple and transparent pricing model focused on utility rather than complexity.
Background
As development progressed, attention turned to a practical question faced by every platform:
How does the platform cover operating costs and generate revenue whilst remaining accessible to users?
A number of approaches were considered, including subscriptions, usage-based charging, advertising and premium account tiers.
The challenge was to identify a model that aligned with the objectives of the platform whilst remaining understandable to users.
Approach
The final model focuses on charging for value-added services rather than participation itself.
Users remain free to:
- Join the platform
- Submit opinions
- Browse the dashboard
- Explore public trends and sentiment
Revenue is generated through optional services, including:
- Report generation
- Publication rights
- Content submission and promotion
- Future API access
This approach allows participation to remain open whilst creating clear commercial value around insight, reporting and distribution.
In future, scope-based tiers have been planned, in order to make the prices more reflective of the geographical areas (and thereby participants) that any services are applicable to.
Principles
Several principles emerged during the design process:
Simplicity over complexity
A pricing model that requires explanation is often a pricing model that requires simplification.
Pay for outcomes, not access
The platform's value lies in the information it produces rather than the ability to submit opinions.
Avoid unnecessary barriers
The objective is to encourage participation and engagement rather than create obstacles to entry.
Observations
The exercise highlighted an important distinction between building a platform and building a business.
Technology creates capability.
Pricing determines whether that capability can be sustained.
Whilst pricing decisions may evolve over time, establishing an initial commercial framework represents an important milestone in transforming an idea into a viable product.
Entry 30 - Stripe Integration and Entitlements
Feature
Stripe payment integration and entitlement management.
Background
Earlier development work focused primarily on collecting, aggregating and presenting opinion data.
The introduction of paid services required a mechanism through which purchases could be processed securely and access rights granted automatically.
Rather than treating payments as a separate concern, the objective was to integrate commercial transactions into the existing platform workflow.
Technology
The implementation consists of:
- Stripe Checkout
- AWS Lambda
- API Gateway
- DynamoDB
- Webhook processing
Users initiate purchases directly from the platform.
A checkout session is created via AWS Lambda and the user is redirected to Stripe's hosted payment page.
Upon successful payment, Stripe generates a webhook event which is processed by the platform.
This event creates or updates the records required to grant access to purchased services.
Architecture
The solution separates responsibilities across multiple data stores:
Eligibility records determine whether a user is entitled to access a service.
Metadata records provide information about the service and its current state.
Content records store the underlying report, publication or submission data itself.
This separation simplifies administration whilst reducing coupling between payment processing and content generation.
Development
The implementation process highlighted a number of practical considerations including:
- Webhook processing
- Environment management
- Deployment automation
- Service entitlement creation
- Metadata synchronisation
- Redirect handling
Several deployment improvements were introduced during this work, including support for Lambda-specific environment configuration files.
Observations
The most satisfying aspect of this work was not the payment page itself, but the successful completion of the full transaction lifecycle:
- User purchase
- Payment processing
- Webhook execution
- Eligibility creation
- Service activation
For the first time, the platform demonstrated the ability to exchange value as well as information.
This represents a significant step from prototype towards product.
Entry 31 – Password Reset Functionality
Feature
Password reset and account recovery.
Background
During a final round of UI tidy-up and testing, I managed to forget my password and was therefore forced to use the password reset functionality.
This immediately revealed a problem.
The password reset workflow was no longer working correctly.
Investigation
Initial symptoms suggested a CORS issue. Browser errors indicated that requests were being blocked before reaching the endpoint.
As often happens with software development, the reported problem was not the actual problem.
Investigation moved through several possible causes including:
- CORS configuration
- API Gateway routing
- Lambda deployment
- Environment configuration
After a considerable amount of testing and diagnosis it became clear that the Lambda function was failing to start correctly.
Root Cause
A number of required environment properties had been removed during deployment.
The function therefore failed during startup before processing any requests.
Unfortunately, the browser surfaced this as a CORS error rather than a startup failure, which made diagnosis considerably more difficult than it should have been.
The issue was eventually traced back to missing configuration values and resolved by restoring the required environment properties.
Outcome
Password reset functionality was successfully restored and tested.
The experience also highlighted an important operational lesson.
Environment configuration is every bit as important as application code. A perfectly valid implementation cannot function if the required configuration is missing.
Observation
Many hours of debugging are spent solving the wrong problem.
The software reported a CORS issue.
The browser reported a CORS issue.
The actual issue was a startup failure caused by missing configuration.
The lesson was simple:
Do not wipe environment properties unless absolutely necessary. If you do, expect things to go wrong.
Development Complete
Entry 31 – Development Complete
Feature
I've run out of those.
Not that there aren't more features that could be added. There always are. But for the purposes of the MVP, we're good.
Observation
There comes a point in every project where adding another feature becomes less valuable than allowing other people to use what already exists. This week marked that transition for Exchange Opinions.
For the first time, the conversation has shifted away from architecture, integrations, and feature development towards deployment, validation, approvals, and user experience. The software is no longer the primary challenge. The next lessons will come from real users interacting with it.
Approach
We spent around forty-eight hours—or at least the equivalent of a part-time working week—building and deploying the production environment.
The environment was designed from the outset to support both scaling and the creation of new regions and deployments. That planning paid off. Although there were a few mishaps along the way, including accidentally deploying Yorkshire and Humberside as Humberside and Yorkshire with a degree of enthusiasm that AWS was only too happy to support, the process largely worked as intended.
Good planning, thinking ahead, and refusing to become too distracted by interesting side quests helped us reach this point.
A supportive partner to bounce ideas off, friends and family willing to test the platform, and—let me mention Gladys, my AI assistant from ChatGPT, for the first time—an AI companion along the way all played their part.
The result is that we now find ourselves waiting for Amazon to respond to a number of relatively routine approval requests.
Functionally, we're ready.
Operationally, we're close.
The remaining dependencies largely sit with external parties.
It's a strange feeling when that happens. For months, progress has been limited only by the number of hours available and the willingness to solve the next problem. Suddenly, the bottleneck becomes an international conglomerate reviewing forms and approval requests.
Whilst they have been considering whether I may send a handful of text messages and emails, I've deployed three environments in four days, fixed the occasional bug, scratched my head over the less occasional mistake, spent a considerable amount of time ignoring CORS warnings, improved deployment tooling, completed a number of technical necessities, and updated the aesthetics of the user interface whilst developing a much stronger understanding of React.
At least I hope they have comfortable chairs.
For now, Exchange Opinions is development complete.
The next chapter belongs to testing, validation, adoption, and whatever surprises real users decide to bring with them.
Publicity and Release
Entry 32 – Chasing the Sunrise
Feature
Photography.
At least, that was the excuse.
Observation
With the development work largely complete and the production environment waiting on a handful of external approvals, attention turned briefly away from software and towards the region that the platform was built to serve.
The original objective was simple enough: collect some photographs for use on the website. Rather than rely on stock imagery, it seemed more appropriate to capture some images of Yorkshire and the Humber ourselves.
What followed was a 4:30am start and a short tour of the Humber Bridge and surrounding countryside in search of a sunrise.
The weather, unusually for Yorkshire, cooperated.
Approach
The exercise unexpectedly served three different purposes.
The first was practical. We needed imagery for the site. The photographs will eventually form part of a carousel and help reinforce the identity of the Yorkshire and Humber pilot region.
The second was personal. Spending time together watching the sun rise over the Humber proved considerably more enjoyable than staring at deployment logs and waiting for emails from Amazon.
The third was routine. Getting up before dawn requires intent. It is difficult to spend months thinking about new beginnings whilst maintaining exactly the same habits. Sometimes the smallest changes are the most symbolic.
As the sun appeared over the horizon, I remember suggesting the words:
“New start.”
At the time it felt like a comment about the morning.
In hindsight it may have been about something else.
Reflection
The photographs themselves turned out well. The Humber Bridge stood against a gradually brightening sky. The estuary reflected the first light of the day. The countryside revealed itself slowly beneath the sunrise.
Yet the images were only part of the story.
For much of the last year, life has been dominated by uncertainty, recovery, learning and rebuilding. Exchange Opinions began as a technical project but gradually became something more than that. It provided structure, creativity, purpose and an opportunity to think about ideas that had been sitting quietly in the background for years.
Watching the sunrise felt strangely appropriate.
The platform is not yet proven. The users have not yet arrived in significant numbers. The reports have not yet been purchased. The larger questions remain unanswered.
But the software is built.
The pilot is ready.
The day has begun.
And sometimes that is enough.
Outcome
A collection of photographs.
A memorable morning.
And perhaps a reminder that progress is not always measured in features delivered, bugs fixed or environments deployed.
Sometimes progress is simply standing still for a moment and recognising that a new chapter has already started.
