顯示包含「軟件開發」標籤的文章。顯示所有文章
顯示包含「軟件開發」標籤的文章。顯示所有文章

2026-04-17

低成本啟動web app

https://stevehanov.ca/blog/how-i-run-multiple-10k-mrr-companies-on-a-20month-tech-stack

採用VPS, Go and SQLite.

索引正確用法

https://jon.chrt.dev/2026/04/15/things-you-didnt-know-about-indexes.html

要點:

  • 索引會使寫入變慢
  • 復合索引中,欄位次序是重要的
  • 文字大小寫是不同的,可以儲存一種case的數據然後用他做索引
  • 索引中可以附帶數據直接返回
實作應用時,確實應按提供的功能,使用正確索引。

2026-04-16

人工智能開發

今天第一次在自己的應用裡面插入人工智能的功能。其實很簡單,就是用自然語言建立任務。把自然語言的句子裡面的成分拆解出來,然後變成任務的參數,再自動填入原來的對話框裡面。

使用了 runpod.io. 本來想用 groq, 但不知何故,他的網頁好像出了問題。

這個應用本身能不能發佈,今天看來其實不重要,重要的是獲得了經驗。

2026-04-01

加固 github page

用 issue 在 github pages 發 blog 有一個問題。對於免費用家,必須用 public repository。這樣,豈非任何人都可以上來寫花我的blog?

研究了一下,原來可以設置只允許 collaborator 寫 issue / discussion。但最長只能設6個月。之後又要來設。唉,公開倉庫就是煩。鬼叫我無錢!

2026-03-27

用 github issue 寫 blog

早前 GitHub 推出 pages,開靜態網頁之路。廣大喜歡靜態網頁的人,對,大多是程序員,或者講求效率節能人士,一擁而上,為社群貢獻了各種生成器。作者平時寫作 markdown 文件,再結合設計樣版,運行工具,生成整個網站。再將其上載至GitHub 發佈 。

這十分繁瑣。連我都不想每寫一篇文章,就在本地跑一轉工具,再push到GitHub。

後來GitHub 自己包攬了這工作。只需作者將 markdown 文件推到repository,即自動觸發生成。

我們要的是直接 online寫。而且能不能更自然一點,不用手動建立一個個的 MD 檔?

Issue 是很好的方式。

坊間也有人做了。有一個服務,你上去登記,連結你的repo,他就出版在他的網站上。這不夠好,沒有 host 在 GitHub。

還有人做了一個工具,它讀出你的issues,視作MD,再調動原來的生成工具。但這仍然要在本機或找服務器跑程序 。

能不能直接在GitHub 上做全套?

應該可以的。

我就叫 Google Gemini 幫手寫 GitHub action, 在有 issue 建立或更改後運行,把它內容轉換成 MD ,即 Jekyll 生成器要求的文件,包括tags. 按既有的設定,這個文件更動會啟動 Jekyll 生成動作。

成功了。現在只要寫 issue,就可以發佈 blog 在 GitHub pages 上。

之後我再公佈這個 action。happy coding!

2026-02-08

Firebase platform

這兩天在Google的Firebase 平台,使得開發了一個日記 。功能包括Google登入,寫日記,用標籤指定分享的人,還可以隨時更換顏色主題 。還有就是導入RSS/atom文件作為日記的篇章 。實際工作時間絕對少過一個工作日。

結論就是Google平台確實是最方便的平台 ,部署很快很方便,而且不用擔心洩密的問題 。至於不是關係數據庫,我覺得這個也不用太花心神 。解放人類的思維吧。

2026-02-05

Gemini to make prototype

居然係最近才知道公司有提供 google gemini 使用,雖然在香港這是被 GOOGLE 禁止的。

不管如何,有個機會要做一個 web app prototype。老闆說你可用 gemini。當然我手頭有其他的 AI 可以幫手,但何不用一下呢。

結果叫我驚艷。我不清楚其他AI是否可以做到類似效果,因為我一般用他們寫 web app 和 iOS app;沒用來做單頁的原型。然後這很成功。範例數據,介面操作,都可以體驗,然後用戶即時接受了這個設計。而這只是我們兩人在三小時內的工作。

雖然這只是原型,但感覺可以稍加改動,用在最後成品之上。

2025-11-22

Xcode Cloud and Github

I practiced this and I could easily release builds to TestFilght for internal testing, and few clicks on Github to have new build for App Store submission.

Preparation:

  1. Once created new project in Xcode, immediately push it to Github to create a new repository as origin. Here we can use the default main branch.
  2. At Github, create a new branch: dev.
  3. At Xcode, switch to dev, and we will always push changes to dev.

At Xcloud Cloud, we will define two workflows. We will trigger them with different conditions for different purposes.

Workflow 1: For track dev branch change, and for TestFlight

  • Trigger: any file change at dev branch.
  • Action is to build, and distribute for TestFlight (internal test)
  • Post action is TestFlight internal test, choose the tester group (define separately)

So, whenever you push to dev branch, will have a new build delivered to TestFlight for your internal testing. Very convenient.

Workflow 2 - For app store distribution

  • Trigger: any file change at main branch
  • Action is build: app store connect.
  • No post action

Usually you don't trigger this. If you want to release it to App Store after some nice build, you:

  1. At Github, create a Pull Request to merge dev into main.
  2. When reply, use Merge.

When dev branch is merged into main, it will trigger Workflow 2. Result is that a new build is created for app store.

You go to App Store Connect page, at release page, pick up this build and assign it to release. 

Happy coding!



2025-11-04

8 Char Indentation

Linux 內核代碼風格:

制表符是 8 個字符,所以縮進也是 8 個字符。有些異端運動試圖將縮進變爲 4 (甚至 2!) 字符深,這幾乎相當於嘗試將圓周率的值定義爲 3。

理由:縮進的全部意義就在於清楚的定義一個控制塊起止於何處。尤其是當你盯著你的屏幕連續看了 20 小時之後,你將會發現大一點的縮進會使你更容易分辨縮進。

現在,有些人會抱怨 8 個字符的縮進會使代碼向右邊移動的太遠,在 80 個字符的終端屏幕上就很難讀這樣的代碼。這個問題的答案是,如果你需要 3 級以上的縮進,不管用何種方式你的代碼已經有問題了,應該修正你的程序。

簡而言之,8 個字符的縮進可以讓代碼更容易閱讀,還有一個好處是當你的函數嵌套太深的時候可以給你警告。留心這個警告。

2025-10-31

django at vercel

忽然間, vercel也支援 django/python 了. 難道用這個更簡單... 

2025-09-25

Sync to iCloud with CKSyncEngine

Discover how CKSyncEngine can help you sync people's CloudKit data to iCloud. Learn how you can reduce the amount of code in your app when you let the system handle scheduling for your sync operations. We'll share how you can automatically benefit from enhanced performance as CloudKit evolves, explore testing for your sync implementation, and more.

Apple dev: wwdc video

https://developer.apple.com/videos/play/wwdc2023/10188/ 

A blog

https://superwall.com/blog/syncing-data-with-cloudkit-in-your-ios-app-using-cksyncengine-and-swift-and-swiftui

2025-08-22

Zero length non breaking space

有個新的api返回的json怎樣都出錯,最後找到是它第一位有個「零長不斷行空格」的神奇字符 。用以下方式清理後就可以了 。

public static String cleanup(String networkData) {
  return networkData.replace((char)65279, ' '); // zero length non breaking space.
}

2025-07-28

2025-07-16

django

折騰了那麼多, 又 vercel 又 supabase; 還是覺得很麻煩. 忽然想起以前聽說過 django, 一試之下深覺這才是終級好東西. 配合 amazon lightsail 環境, 簡單又便宜.

雖然有 AI 幫寫程式, 但還是越少code越好啦. 

2025-05-24

which DB?

在 cloudflare D1 玩了幾日,後來還是選擇返 Supabase. 理由是它已有 data API和其他功能,比如 authentication.

2025-04-22

supabase的AI, functions和API

再探了一下 supabase.

之前我想好了新app的 data tables. 當然只是草稿了 table name 和相關欄位名. 面對 supabase 介面, 我當然不想再用 GUI 慢慢建立數據表. 我看到了它內置的 AI 命令介面: 右上角綠色菱形. 

AI

那我就說

follow tables please create them in effortapp schema: i will list the table name, followed by a colon, then fields. you try to define the type for them. and also you can see the FK between them.  
user: id, email, name
team: id, name 
project: id, name, team id, start date, end date, ....


然後它就生成了相關的 create table SQL, 一鍵完成. 看了一下, 連 foreign key 也是正確的. 當然我用的約定俗成的命名慣例應該有幫助.

我再來:

also create two many-to-many tables to link up relevant tables.

user_in_team: link up user and team  

task_by_user: link up task and user.

當然也完美運行, 2 個多對多的關係表也完成了. 甚至連 on delete cascade 也寫好.

我還打開 entity diagram 看了一下, 應該沒問題.

Database Functions

然後我看到 supabase function. 也許是相當於 oracle 的 stored procedures. 問了AI確認, 我就叫它為幾個表都寫上 CRUD:

create CRUD functions for user, team....  tables. execute the code directly.

似乎它不會立即運行, 我還是要手動按一下運行鍵. 一下子20個 function 就出現了. 

API

我想到, 這麼好的東西, 也許可以經 HTTP 使用吧, 那豈不美妙?

當然是可以的:

POST https://<your-supabase-url>/rest/v1/rpc/create_user
Authorization: Bearer <your-jwt-token>
Content-Type: application/json

{
  "p_email": "user@example.com",
  "p_name": "User Name"
}

好吧, 似乎連 Vercel 都可以省去了...


2025-04-06

step to create a vercel project with nodes

- create a github repo with gitignore of node.
- clone repo to local.
- at the directory, npm init to setup node app
- local run vercel to setup a new project and deploy. use default settings.
- confirm at vercel site the new project should be created.
- access root will be 404.

2025-03-25

AI vibe coding 心得

實戰了幾輪, 付出真金白銀體驗, 有些體會:

DO:

  • 最好先有一個 database schema, 同 AI 交待這個schema, 他會少犯錯. 
    • 直接給他看 ER 圖也可以, 如 cloude 甚至注意到 ER 圖內的 relationship. 用圖的話, 要指定用哪一款數據庫. (mysql? oracle? prostgresql? ... )
    • 不用圖, 給 CREATE TABLES 也可以
    • 要設定好主鍵 PK 和外鍵 FK.
  • 在第一個提示就說好要求和細節. 就當你只有一次機會, 長一點沒關係. 
    • 為了日後人手接力, 要交待: 平台為何 (如 Vercel), 有什麼數據庫 (如 Supabase), 它們用什麼方法連 (Supabase data API), 用的語言是什麼 (javascript), 要用什麼主要技術 (node js). 如果是 web app, 交待要用的 js 庫 (如 JQuery), CSS (如 bootstrap), template engine (如 Pug), 相關技術的 preference (如 HTMX).  
  • 每次改動不要太多, 要限制他改的範圍.
  • 及時TEST, 及時追加修正.
  • 提醒AI要一並修改相似功能.
  • 如DEBUG有阻礙, 盡量目測發現更多線索提供給AI. 
  • 處理有登入情況時, 提醒AI要為各功能加上token或cookie. 不然這些功能在加上LOGIN後可能會FAIL.

Do NOT:

TBC

Complete app by Cloude

只是一次指令就做了完整node app,按要求用埋pug template,連埋去 supabase。

我都真係無咩好講了。

為何作夢

原來這就是為何夢境中多是影像,沒聲音和其他感受。影片說,是因為我們夜晚入睡時,視覺系統沒有眼睛輸入的信號,反而將神經內電流解釋成以前的,或想像出來的畫面。夢境所見,是感情深處的事件重放。我想到,其它感官並沒有視覺關閉得那麼徹底,所以在夢中很少出現。