← Financial Cloud CloudCloud Club · 挑戰

極點宏觀|Financial Cloud Cloud · 挑戰

Full Stack Challenge: Community Day Board App

Series: Challenge

Challenge: 06

文章
Kiro 工作坊
01 使用 Kiro 建置:他加祿語學習 App 的提示優先產品設計工作坊
Kiro 工作坊
02 使用 Kiro 建置:他加祿語 學習 App 的教育優先開發技巧工作坊
Kiro 工作坊
03 使用 Kiro 建置:他加祿語 學習 App 的深入開發流程工作坊
Kiro 工作坊
04 使用 Kiro 建置:將 他加祿語 學習 App 在地化為中文變體工作坊
Kiro 工作坊
05 使用 Kiro 建置:他加祿語 卡片的文法與發音補強管線工作坊
Kiro 工作坊
06 使用 Kiro 建置:他加祿語 學習 App 中可審查的獨特額外例句工作坊
Kiro 工作坊
07 與 Kiro 同行:晶圓廠工程健康度 Hook 工作坊
Kiro 工作坊
08 與 Kiro 同行:蝕刻製程視窗風險測試自動化工作坊
Kiro 工作坊
09 與 Kiro 同行:黃光微影漂移風險開發工作坊
Kiro 工作坊
10 工程團隊入門 — 日常工廠值班使用 fab spc drift sync portal
Kiro 工作坊
11 工程團隊附錄 — fab spc drift sync portal 的日常工廠值班使用
Kiro 工作坊
12 Kiro:規格驅動工廠軟體的現場工程工作坊
Kiro 工作坊
13 Kiro:實作 Lab — 從零建置具型別的 Factory Risk Portal
Kiro 工作坊
14 Kiro:工程開發人員的提示、程式碼和型別標準手冊
Kiro 工作坊
15 Kiro:為什麼強 React 提示可以防止型別宣告錯誤啟動
Kiro 工作坊
17 與 Kiro 一起建構:建立工廠自動化入口網站 React UI
Kiro 工作坊
18 與 Kiro 一同建構:打造工廠自動化入口網站背後的自動化分析引擎
Kiro 工作坊
19 與 Kiro 一起實作:將 AI 工廠自動化輔助程式新增至工廠自動化入口網站
Kiro 工作坊
21 Kiro:2 小時專業開發人員工作坊指南
Kiro 工作坊
22 Kiro:從零建置 Fab SPC Drift Synchronization Portal
Kiro 工作坊
23 Kiro:提示詞庫與深度程式碼說明附錄
Kiro 工作坊
30 與 Kiro 一同建構:建立工廠自動化入口網站 UI
Kiro 工作坊
31 與 Kiro 一同建構:打造工廠自動化入口網站背後的自動化分析引擎
Kiro 工作坊
32 與 Kiro 一起實作:為工廠自動化入口網站增添 AI 工廠自動化助理
Kiro 工作坊
33 與 Kiro 一起開發:重建 CME Direct 風格的量化損益排行榜 UI
Kiro 工作坊
34 與 Kiro 一起開發:重建損益排行榜背後的量化分析引擎
Kiro 工作坊
35 與 Kiro 一起建構:適用於量化排行榜的 AWS AI 驅動交易台助理
Kiro 工作坊
36 單頁交易平台 SOP
Kiro 工作坊
AgentCore
A1 使用 AgentCore 與 Strands 建構:Gateway MCP 工具織網開發者工作坊
AgentCore
A2 使用 AgentCore 與 Strands 建構:受治理的多 Agent 風險系統開發者工作坊
AgentCore
A3 使用 AgentCore 與 Strands 建構:執行期主權風險代理人開發者工作坊
AgentCore
模擬考場
E1 用 Vibe Coding 打造多語言 AWS 證照模擬試題上線系統
模擬考場
E2 利用 Vibe Coding 開發技巧打造 AWS 證照模擬練習室
模擬考場
E3 打造靜態 AWS 模擬考場背後的練習引擎
模擬考場
Amazon Q
Q1 Amazon Q:ACM 憑證自動更新的CloudShell優先開發人員工作坊
Amazon Q
Tagalog 練習室
T1 為 AWS Manila Community Day 打造 Tagalog 學習 App:提示詞優先的產品設計
Tagalog 練習室
T2 為 AWS Manila Community Day 打造 Tagalog 學習 App,採用教育優先的開發提示
Tagalog 練習室
T3 為 AWS Manila Community Day 打造 Tagalog 學習 App 的開發流程深度解析
Tagalog 練習室
T4 將 Tagalog 學習 App 在 AWS Manila Community Day 情境中在地化為中文版本
Tagalog 練習室
T5 為 AWS Manila Community Day 打造 Tagalog 卡片打造文法與發音補強流程
Tagalog 練習室
T6 為 AWS Manila Community Day 打造 Tagalog 學習 App 的 Extra Examples 更獨特且可審閱
Tagalog 練習室
路線圖
R1 企業級 Data Analytics Roadmap 一百個深度情境題
路線圖
R2 前端開發路線圖:真實企業場景
路線圖
香港 Community Day
C1 伴隨 AWS Community Day 的香港週末:從雲端技術論壇到維港璀璨夜景
香港 Community Day
C2 講者的奢華週末:分享您的 AWS 故事,讓香港成為您的專屬舞台
香港 Community Day
C3 香港七十二小時:AWS Community Day 講者的極致之旅
香港 Community Day
馬尼拉 Community Day
C4 AWS Community Day Manila:一場連結雲端技術、城市文化與真摯友誼的快樂週末
馬尼拉 Community Day
C5 AWS Community Day Manila:雲端建立者在菲律賓感受最幸福的精神
馬尼拉 Community Day
C6 AWS Community Day Manila:在快樂之城建構、打破、重來,並找到歸屬
馬尼拉 Community Day
C7 菲律賓馬尼拉初次造訪建議
馬尼拉 Community Day
菲律賓 × 香港
C8 菲律賓香港資本市場升級
菲律賓 × 香港
回測
B1 使用 Bedrock AgentCore 與 Strands Agents 建立機構級 Amazon 純做多 (Long-Only) 回測代理
純做多 AMZN 代理:AgentCore、Strands 與可稽核的 Backtrader 帳本。
B2 使用 Backtrader、AgentCore 與 Strands Agents 建立具市況感知能力的 Amazon 部位管理
把市況當成部位控制,而不是圖表註解。
B3 使用 Nasdaq、S&P 500、Dow、AgentCore 與 Strands 建立相對於基準的 Amazon 進出場時機系統
相對 Nasdaq、S&P 500 與道瓊來判斷 AMZN 時機。
B4 使用 Bedrock AgentCore、Strands Agents 與 Backtrader 建立受治理的 Amazon 交易歷史工廠(Trade-History Factory)
把回測做成可稽核的交易歷史工廠。
B5 使用 Bedrock AgentCore 與 Strands Agents 建立智慧代理型 (Agentic) Amazon 回測營運模型 [Part 1]
先建立營運模型,再爭論結果。
B6 為 Amazon 擇時與部位管理建立客製化 Cerebro 程式碼說明 [第 2 部分]
先講 Cerebro 引擎,再講圖表。
B7 為 Amazon 策略結果與經驗教訓建立交易員審閱紀錄 [Part 3]
把策略排名寫成交易員審閱紀錄。
B8 使用 AgentCore 與 Strands 建立受治理的 FSI Amazon 部位管理 Playbook [Part 4]
受治理的 FSI Amazon 部位管理手冊。
B9 使用 Amazon Bedrock AgentCore 建立主權風險交易代理,分析殖利率差、FX 避險與債務重新定價
主權風險代理:殖利率差、外匯避險與債務重定價。
B11 建置現代波動率交易與合法泰國復原規劃代理程式:記憶體驅動的 Strands 多代理程式風險防護系統
記憶驅動的 Strands 代理:波動率與泰國復原規劃。
B12 使用 Amazon Bedrock AgentCore Memory 建構空頭跨式部位交易風險治理
空頭跨式部位的交易風險治理。
B13 在 Amazon EKS 上建構生產環境就緒的信用與收益質押 AI 智能體
在 EKS 上跑生產級信用與收益質押代理。
挑戰
01 週末生產力挑戰:Fab SPC 漂移同步入口網站
Fab SPC 漂移審查與建議入口網站。
02 週末生產力挑戰:Quant P&L Commander — AWS 上由 AI 驅動的交易生產力入口網站
AWS 上由 AI 驅動的交易生產力入口網站。
03 週末煩人的任務挑戰:交易台在雲端、鏈上、空中執行摘要
DeskPulse 日常交易執行摘要。
04 週末 Agent 挑戰:上午 6 點交易風險審查
無人值守、以證據為基礎的晨間交易風險簡報。
05 Weekend Creative Challenge: Leadership Card Game
瀏覽器版創意引導卡牌。
06 Full Stack Challenge: Community Day Board App
瀏覽器版活動溝通空間。
領導力卡牌
01 Leadership Card Game: 雲端還沒自動化的最後一項本事:像領導者一樣說話
寫給 建構者的現場隨筆——談語言、勇氣,以及 Leadership Card Game
02 領導力回合的解剖:Leadership Card Game 實際怎麼玩
給 建構者的引導員實地指南——讓演練嵌進真實會議
03 Leadership Card Game: 當機會不再屬於主辦者
寫給 建構者的現場隨筆:權力轉移、多語領導力練習夜,以及走完入口、資源、敘事的職涯弧線
04 週末創意挑戰:Leadership Card Game
一篇建構者手記:願景、架構,以及週末創意挑戰教會我的事
05 從週末挑戰專案到 $1,386 群眾募資:改變你在職場現身方式的領導力練習
一個週末做出的作品,變成 600 張卡的線上領導力練習室,並募到 $1,386。
06 從週末挑戰專案到 $1,386 群眾募資:進入科技產業的第一天路徑
一個週末挑戰如何變成具備 600 張卡、由 AWS 驅動的多語產品,並募到 $1,386?
07 從週末挑戰專案到 $1,386 群眾募資:用轉移機會建立專業品牌
一個週末挑戰把領導想法做成能跑的多語產品,並募到 $1,386。
08 Leadership Card Game — 群眾募資活動
募資目標: HKD 5,000 已募金額: HKD 1,386 距目標還差: HKD 3,614 進度: 28% 創作者: D.C. Dan · L.L. Diana · L.K. Lva 所在地: 日本、香港、新加坡 投資人權益: 即期價值、私密會員卡牌編輯器雲(Private Membership Card…
09 PR/FAQ 01 — Leadership Card Game 面向社群建構者正式推出
「逆向工作法」文件 · 對外新聞稿 + FAQ 產品: Leadership Card Game 受眾: 社群經理、志願組織者、職涯早期建構者
10 PR/FAQ 02 — 企業引導員採用 Leadership Card Game 進行現場領導力演練
「逆向工作法」文件 · 對外新聞稿 + FAQ 產品: Leadership Card Game 受眾: 學習與發展負責人、人員管理者、敏捷教練、企業引導員
10 PR/FAQ 03 — 多語 Leadership Card Game 為建構者擁有權開放全球練習室
「逆向工作法」文件 · 對外新聞稿 + FAQ 產品: Leadership Card Game 受眾: 全球 建構者、雙語社群、跨境產品團隊、開源導師
AWS Builder Center
01 AWS Builder Center、社群精神與 AWS Builder Jacket
霓虹訊號、共享創意,以及為建構者打造的外套。
02 走進 AWS Builder Center:一座能學習、貢獻,也讓人有歸屬感的全球技術平台
一段精彩旅程,不一定從機場開始。
03 AWS Community Builder 的巨大成功
當建構者公開分享,整個社群就會一起前進。
04 AWS Builder Center 的巨大成功
一座為好奇心打造、充滿活力的全球街區。
05 週末走進 AWS Builder Center:從社群靈感到令人難忘的 AWS Builder Jacket
星期五晚上,開始於建構者熟悉的感覺:有一個點子,正卡在問題與可能性之間。

Disclaimer: This project is an independent creation for the purpose of learning and practicing leadership skills. It is not an official Amazon Web Services (AWS) product or project, nor is it affiliated with, sponsored, authorized, or endorsed by AWS or Amazon.com, Inc. All trademarks and brand names belong to their respective owners.

Unofficial Project: Created independently by builders solely for educational and leadership development purposes.

No AWS Affiliation: This project is not an official Amazon Web Services (AWS) product, nor is it maintained, sponsored, or officially supported by AWS or Amazon.com, Inc.


Community Day attendees often use different messaging platforms, while international speakers may not want another app, account, or request for personal contact details. Community Board provides a simple browser-based event room for sharing updates, locations, meeting details, and images. Powered by AWS Lambda and Amazon S3, the mobile-first MVP is practical and inexpensive for short-term event communication.

社群日留言板首頁
社群日留言板首頁
社群日留言板系統設計
社群日留言板系統設計
社群日留言板提案
社群日留言板提案
社群日留言板使用旅程
社群日留言板使用旅程

Try the application: Community Board

Github: Repo link


Conference communication should be easy. Too often, it is not.

A conference may bring together local participants, international speakers, sponsors, volunteers, and organizers for only one or two days. These people need to exchange practical information quickly: where a session is being held, whether a speaker needs an adapter, when a room has changed, where to meet after a talk, or how to share a photo from the event. Yet the usual communication options create friction. Some attendees use WhatsApp, some use Facebook Messenger, and others do not have either service. International experts may not want to install another application, create another account, or expose a personal phone number just to communicate during one conference.

I built Community Board to remove that barrier. It is a lightweight, browser-based communication application for conference speakers and participants. A user opens a web page, enters the event access token, picks the correct event room, adds a display name, and starts sharing text or images. There is no mobile app to download and no social-media account to exchange.

The project deliberately uses a small full-stack architecture on AWS. A mobile-first front end runs in the browser, an AWS Lambda function provides the application logic, and Amazon S3 stores the event data and uploaded images. The result is an MVP that is easy to explain, inexpensive to operate at small-event scale, and practical to improve after testing it with real conference users.


Vision and What It Does

The vision for Community Board is simple: give everyone at a conference a shared communication space that works from a normal web browser.

This idea came from a real interoperability problem. Conference participants do not all belong to the same messaging ecosystem. Asking everyone to use one consumer chat platform sounds easy, but it creates several problems:

  1. Not everyone has the same app. An international speaker may not use the messaging platform that is common in the host country.
  2. Installing an app takes time. Conference communication is temporary and urgent. Downloading an app, creating an account, verifying a phone number, and reviewing permissions is too much friction.
  3. Personal contact details may be exposed. People may not want to share a personal phone number or social-media identity with a temporary group.
  4. The context is fragmented. Messages can be divided across private chats, group chats, email threads, and social platforms.
  5. Event information has a short useful life. A simple room for a specific event may be more appropriate than a permanent community account.

Community Board addresses these issues with event-specific rooms and a token-gated entry flow. The landing page retrieves the list of events and presents each one as a clear card. A participant enters the access token supplied by the organizer and selects the relevant event. The browser then opens that event's chatroom and carries the event ID and token in the request.

Inside the chatroom, participants can:

● choose a display name;

● post a text message;

● attach an image;

● see the sender and local display time for each post;

● manually refresh the room;

● receive an automatic update every 60 seconds;

● open an image in a lightbox;

● zoom and move an enlarged image with mouse, pointer, or touch controls; and

● return to the event list without navigating through an installed application.

The interface also remembers the user's display name in browser local storage. This is a small UX detail, but it matters during a busy event because the participant does not need to type the same name whenever the page is revisited.

The primary users are conference speakers and attendees, but the same pattern could support workshops, community meetups, hackathons, temporary training rooms, volunteer teams, or user-group events. The application is intentionally not positioned as a replacement for a large enterprise collaboration platform. Its strength is focused, temporary, low-friction communication.


Full-Stack Breakdown: From Pitch to Launch

I approached the project by connecting each stage to the product journey discussed across the Code.TV series: pitch, prototype, MVP, UX, and launch. That structure helped me avoid beginning with technology for technology's sake. Instead, each implementation choice had to support a user need.

1. Pitch: One Browser, One Room, No App Install

The pitch was based on a single sentence:

Community Board lets conference speakers and participants communicate in an event-specific browser room without installing an app or exchanging personal social-media accounts.

A useful pitch needs a specific user, a recognizable problem, and a clear outcome. “Build a chat app” would have been too broad. By narrowing the scenario to conferences, I could make better decisions about identity, access, refresh speed, data retention, and interface design.

The conference setting also gave me a practical test for every feature. Does it help a speaker or participant communicate during an event? If not, it probably does not belong in the first release.

2. Prototype: Prove the Journey Before Building the Backend

The next step was to prototype the simplest user journey:

  1. Open the Community Board landing page.
  2. Enter an event access token.
  3. Select an event.
  4. Enter a display name.
  5. Read and post messages.
  6. Optionally attach an image.

I built the interface with plain HTML, CSS, and JavaScript. This kept the prototype direct and made the browser behavior easy to inspect. The landing page and chatroom are separate files, which creates a clear boundary between event discovery and room participation.

The landing page fetches an events.json document from the hosted site and falls back to a local relative file if the primary request fails. It validates that an access token has been entered before opening a room. It also escapes event values before inserting them into generated markup, which reduces the risk of treating event data as executable HTML.

The chat prototype established the main interaction patterns: a fixed header, a scrollable feed, and a composer at the bottom of the screen. I used a mobile-first layout because many conference users will open the board by scanning a link or typing a URL on a phone.

3. MVP: Complete the Smallest Useful Full Stack

For the MVP, I needed more than a visual prototype. Messages had to move from the user's browser to an AWS backend, survive a page refresh, and become visible to other participants.

The browser calls an AWS Lambda Function URL. A GET request loads the board for one event, while a POST request submits a display name, text, and an optional image. The Lambda function validates the event and its token, reads the current board JSON from Amazon S3, adds the new message, and writes the updated JSON object back to S3.

Images follow a related path. Before upload, the browser uses a canvas to resize the image so its longest edge is no more than 2,000 pixels and converts the result to JPEG at a defined quality level. The image is then sent as a data URL in the request. Lambda validates the supported image format and request size, decodes the image, gives it an event-specific UUID filename, and stores it under the board's image prefix in S3. The message record stores the resulting public image path rather than embedding the full image payload in the event JSON.

This was enough to make the application genuinely useful. It supported multiple event rooms, text, images, persistence, refresh, validation, and a deployable browser experience.

4. UX: Reduce Friction in a Busy Conference Environment

Conference software is often used while someone is walking, preparing to speak, or switching between sessions. The interface therefore needed to be readable and forgiving rather than feature-heavy.

I used large tap targets, high-contrast borders, clear focus indicators, responsive sizing, and safe-area spacing for mobile devices. Status text tells users whether the board is locked, refreshing, synchronized, sending, or unable to load. The composer supports Enter to send and Shift+Enter for a new line, while still providing a visible Send button for touch users.

Image handling received extra attention. A user sees a preview before sending and can remove the selected image. Posted images can be opened in a full-screen lightbox. The viewer supports zoom buttons, the mouse wheel, pointer dragging, and a two-finger pinch gesture. These capabilities are useful when users share a room map, slide photo, timetable, or equipment image.

I also avoided unnecessary account creation. The event token provides lightweight room gating, while the display name creates enough identity for an informal conference board. This is an intentional MVP trade-off, not a complete authentication system.

5. Launch: Deploy, Observe, and Create a Feedback Loop

The launch stage turned the project into a public web application rather than a local demonstration. The static front end and board assets are hosted through the AWS-backed website, while the server-side behavior is exposed through a Lambda Function URL.

I added structured log messages around input, output, S3 reads, S3 writes, image uploads, validation failures, and message counts. Those logs make troubleshooting much easier than scattered string messages. For example, I can distinguish an unknown event, invalid token, malformed JSON body, failed S3 read, and failed image write.

The application refreshes after a successful post and also polls every 60 seconds. Polling is not as immediate as a WebSocket connection, but it is easy to operate and adequate for this first version. The manual Refresh button helps when a participant expects an urgent update.

Launching an MVP does not mean the application is finished. It means the complete product loop is now available: users can try the app, I can observe where they struggle, and the next version can be based on evidence rather than assumptions.


How I Built It

Front-End Structure

The front end consists of two main pages.

index.html is the event selection page. It displays the Community Board introduction, asks for an access token, loads the event list, and creates one card for each available event. When the user chooses a card, the page adds both the event ID and token to the chatroom URL.

chat.html is the communication experience. It reads the event ID and token from the query string, loads the corresponding board, renders messages, and enables the composer. The display name is saved to local storage. Text is escaped before rendering, and image URLs are only accepted if they match the expected application domain and filename pattern.

I chose framework-free JavaScript because the application has a small number of screens and a straightforward state model. That reduced build tooling and made deployment as static files simple. It also forced me to think carefully about browser APIs, DOM updates, validation, and asynchronous requests.

Backend Structure

The backend is a Node.js 20.x Lambda function using the AWS SDK for JavaScript. It accepts GET, POST, and OPTIONS requests through a Lambda Function URL.

For GET, the function:

  1. reads the event ID and token;
  2. checks whether the event is known;
  3. compares the supplied token with the expected value using a timing-safe comparison;
  4. reads community-board/event_{id}.json from S3;
  5. creates an empty in-memory board if the object does not exist; and
  6. returns a sanitized board response.

For POST, the function:

  1. parses the JSON request body;
  2. validates the event and token;
  3. cleans and limits the display name and message text;
  4. verifies that either text or an image is present;
  5. validates and decodes an optional image;
  6. writes the image to S3 with a UUID-based filename;
  7. reads the existing board;
  8. appends the new message;
  9. retains the most recent 300 messages;
  10. writes the updated board JSON to S3; and
  11. returns the created message and update timestamp.

I limited names to 40 characters and messages to 2,000 characters. The Lambda function also places a maximum size on an encoded image request. These controls protect the application from accidentally oversized input and keep the board appropriate for quick event communication.

Key Decisions

One important decision was to store each event board as a JSON object in S3 instead of introducing a database in the first release. This made the architecture small and the stored state easy to inspect. For a controlled event with moderate message volume, it is a practical way to validate the product idea.

Another decision was to use scheduled polling rather than real-time sockets. A 60-second interval reduces implementation and operational complexity. Users can also refresh manually, and the page reloads the board immediately after a successful post. This delivers a “near-live community board” experience without pretending the MVP is a high-throughput real-time messaging service.

Finally, I kept access control intentionally lightweight. Each recognized event has a matching token, and the backend validates every read and write. The token is a shared event secret, not individual authentication. That is sufficient for an MVP and a limited event audience, but production growth would require a more robust identity and authorization design.


Challenges and How I Overcame Them

Challenge 1: Supporting Images Without a Complex Upload Workflow

Allowing images can quickly complicate a simple application. Large phone photos increase request size, take longer to upload, and should not be stored directly inside the board JSON.

I addressed this in two stages. First, the browser resizes the image before sending it. Second, Lambda separates the binary image from the message record. The function writes image bytes to an S3 image prefix, then stores only a generated filename and public path with the chat message. This keeps event JSON smaller and lets the browser load an image as a normal web asset.

Challenge 2: Keeping User-Provided Content Safe to Render

A communication board displays values that come from users and event configuration. Inserting those values directly into HTML would be unsafe.

The front end escapes text, names, event labels, and other dynamic strings before rendering them. Image sources are restricted to the application's expected domain and filename structure. The backend also removes control characters and enforces length limits. This is not a substitute for a full security review, but it is a strong baseline for the MVP.

Challenge 3: Making the Experience Work on Phones

A desktop-only chat would miss the real conference use case. Mobile browsers also introduce details such as viewport sizing, safe-area insets, virtual keyboards, touch gestures, and small tap targets.

I designed the layout around 100dvh, safe-area environment values, responsive widths, and controls large enough to tap. The feed scrolls independently between the header and composer. The image viewer provides both button controls and touch gestures. Inputs use a 16-pixel font size, which also helps avoid unwanted zoom behavior on some mobile browsers.

Challenge 4: Diagnosing Distributed Failures

A failed message could originate in the browser, Function URL request, token validation, image parsing, S3 read, or S3 write. Without useful logs, every failure can look the same.

The Lambda code writes structured JSON logs with a timestamp, label, and relevant metadata. It records the start and result of S3 operations and summarizes requests without printing the token value. This gives me a traceable path through the backend while avoiding direct token logging in the input summary.

Challenge 5: Balancing Simplicity With Correctness

The biggest design challenge was knowing where simplicity becomes a limitation. S3 JSON storage is easy to understand, but concurrent writes could overwrite one another if many users post at exactly the same time. A shared token is convenient, but it is not user-level identity. Polling is simple, but it is not instant.

I treated these points as explicit MVP constraints rather than hiding them. The current version proves the product journey. A larger production version could move messages to Amazon DynamoDB, add Amazon Cognito for identity, use AWS AppSync or API Gateway WebSocket APIs for real-time updates, put Amazon CloudFront in front of static assets, and introduce moderation and retention controls. The important lesson is to evolve architecture in response to demonstrated demand.


AWS Services and Architecture

The deployed application uses the following core AWS capabilities:

● Amazon S3: hosts the website content and stores event JSON documents and uploaded images.

● AWS Lambda: runs the Node.js backend that validates access, reads boards, creates messages, processes images, and updates board state.

● AWS Lambda Function URL: exposes HTTPS endpoints used directly by the browser for GET and POST requests, with CORS configured at the Function URL.

● AWS Identity and Access Management (IAM): grants the Lambda execution role only the required S3 read and write actions for event JSON and image object paths.

● Amazon CloudWatch Logs: receives the Lambda function's structured console logs for operational troubleshooting and observation.

Request Flow

Step 1: Accessing Static Assets

The conference participant loads static HTML pages and the event list over HTTPS from Amazon S3.

Step 2: Initializing the Web Client

The browser opens chat.html with a specific event ID and authentication token, initializing the client-side JavaScript application.

Step 3: Invoking the Serverless Backend

The JavaScript client sends HTTPS requests (GET to fetch the message board, POST to submit messages/images) directly to an AWS Lambda Function URL.

Step 4: Executing Business Logic

AWS Lambda receives the incoming request and executes Node.js application logic and input validation.

Step 5: Managing S3 Data Persistence

The Lambda function uses GetObject and PutObject calls to store and retrieve data in S3:

● Event JSON: Reads/updates message board state at community-board/event_{id}.json.

● Image Media: Uploads/retrieves user attachments at community-board/../../cummunity_board/img/....

When a user reads a room, the browser sends the event ID and token to the Function URL. Lambda validates the pair and returns the corresponding board from S3. When the user posts, Lambda validates and cleans the input, optionally stores an image, appends a message, and writes the updated board. The browser then loads the newest state and renders it.

The Lambda IAM permissions are scoped to the relevant event JSON and image prefixes. The function uses environment variables for the bucket name, key prefix, and public image base. This makes the code easier to move between environments without changing every storage path.


What I Learned

The most important lesson was that full-stack development is not simply “front end plus backend.” It is the design of a complete path from a human need to a reliable interaction.

I learned to begin with friction. The key problem was not a missing chat technology. Many excellent messaging tools already exist. The problem was that conference visitors may not share an app, account, or communication norm. Once I framed the project around that barrier, a browser application became the natural solution.

I also learned that a prototype and an MVP answer different questions. The prototype asked whether the user journey was understandable. The MVP asked whether the whole system could accept, store, retrieve, and display real messages and images after deployment. Connecting the browser, Lambda, IAM, and S3 made the application real.

Working with serverless AWS services reinforced the value of small operational boundaries. Lambda contains the request logic. S3 contains durable objects. IAM defines what the function may access. The Function URL gives the browser a direct HTTPS entry point. Each part is understandable by itself, but the application only succeeds when their permissions, request formats, CORS behavior, object keys, and response shapes agree.

The image feature taught me to think across the whole stack. Resizing in the browser improves the upload before it reaches AWS. Lambda validates the type and size rather than trusting the client. S3 stores the binary asset separately. The event JSON stores only the reference. The front end validates the returned image path and provides an accessible viewing interaction. One visible feature required coordinated decisions in UX, networking, security, compute, and storage.

I learned the importance of designing failure messages. “Something went wrong” is not enough when testing a distributed application. The UI distinguishes missing tokens, missing names, empty messages, refresh failures, upload problems, and backend errors. The Lambda function distinguishes unknown events, invalid tokens, malformed input, unsupported methods, and storage failures. Structured logs then help connect user-visible behavior to backend activity.

Finally, I learned to treat limitations as part of responsible engineering. The current Community Board is appropriate for a small, controlled conference use case, but I would not claim that one mutable JSON object is the right storage pattern for unlimited concurrent chat. I now have a clearer migration path because the MVP exposed the boundaries: stronger authentication, atomic message writes, event administration, moderation, retention policies, rate limiting, and real-time delivery can be added as real usage justifies them.


What Comes Next

My next steps would focus on production readiness and organizer experience:

  1. move messages to Amazon DynamoDB for independent, concurrency-safe records;
  2. add time-to-live policies so temporary event messages expire automatically;
  3. use Amazon Cognito if events require individual identities;
  4. add rate limiting, abuse controls, and moderation tools;
  5. protect sensitive configuration through managed secrets rather than source code;
  6. add an organizer page for creating events and rotating access tokens;
  7. improve accessibility testing with keyboard-only and screen-reader journeys;
  8. add automated front-end and Lambda tests;
  9. add infrastructure as code for repeatable deployment; and
  10. evaluate real-time delivery if users need updates faster than polling.

The project does not need all of those features to demonstrate its value today. Community Board already shows how a focused idea can become a complete deployed application by moving through pitch, prototype, MVP, UX, and launch.


Conclusion

Community Board solves a practical conference problem with a deliberately simple AWS full stack. Speakers and participants can communicate through a browser without installing an app, joining a social network, or exchanging personal contact details. Event rooms organize the conversation, shared tokens provide lightweight gating, and text and image posts cover common event needs.

Building the project helped me connect product thinking with cloud engineering. The pitch defined the audience and friction. The prototype clarified the journey. The MVP connected the browser to persistent AWS services. UX work made the result practical on mobile devices. Launch and logging created the foundation for real feedback.

Most importantly, the project reminded me that successful full-stack applications do not have to begin with a large architecture. They begin with a specific person, a specific obstacle, and the smallest complete experience that removes it.

Application: https://vertexmacro.com/cloud_club/demo/community-board/index.html

Public repository: https://github.com/dchan-dev/aws-community-board