Tech

28 Aug 2024

20240828

mdx + astro もりもとさんに紹介したら astro というのは割と有名なツールらしい。mdx は md の拡張だと思うけど使ったことない。 Cloudflare と AWS Cloudflare のざっくりとした所感としては API レベルで AWS 互換となっているサービスが多く(例: AWS S3 互換の Cloudflare R2) 使いやすく、それでいてコストは低い印象を持っている。 会社としても機能拡大するために Baselime はじめ買収が目立ち、勢いが目立つ。 AWS でできることはなんでもできまっせ状態を目指しているのかもしれない。 開発環境は fly.io のほうがずっと開発者体験がよくて気に入っている。 AWS は大きくなりすぎたし万人向けになりすぎた。もっとフットワーク軽くデプロイしたい。 とはいえ、機能要件は割と AWS に並んできたけど、非機能要件はまだまだだいぶ未熟。 特に IAM, AWS Organizations, IAM Identity Center 周りは比するべくもない。

25 Aug 2024

20240825

少し幹から離れると情報が過疎になる fly.io にデプロイしていている個人開発アプリの staging 環境が整ってきた。 以下の要素をうまく同期できているのがよい。 AWS Organizations + IAM Identity Center のベストプラクティスに則ったメンバーアカウント(SDLC/awesomeapp-stg) rails の config/ENVIRONMENT.rb rails の credentials/ENVIRONMENT.key fly.io の fly secrets set RAILS_MASTER_KEY=$(cat config/credentials/.key) fly launch が生成した Dockerfile デフォルトだと production 環境をデプロイしようとするので、調整が必要だったが、こういうニッチな情報はネットにないので自分で試行錯誤する必要があった。 これはこれでどこかでブログにまとめておこう。

14 Aug 2024

20240814

ワンライナと爪楊枝群症候群は揮発性のコード シングルクォートが含まれるフィールドを INSERT するのにひさびさの爪楊枝群症候群(leaning toothpick syndrome) を発動してしまった。 DB に入ればいいんだよ。入れば。 開発環境だからと傍若無人な振る舞いを許している。 postgresql から export して psql> COPY chartulas to '/tmp/chartulas.csv' delimiters','; ➜ sort -k1 -n /tmp/chartulas.csv | less rails で特定のテーブルのみを初期化して auto increment のカウンタもリセットしてから irb> Chartula.delete_all irb> ActiveRecord::Base.connection.reset_pk_sequence!('chartulas') import の SQL を乱暴に作成して(シングルクォートは double them up しろ というのを初めて知った) $ ruby -r csv -e "CSV.parse(ARGF.read, headers: true) do |row| row[1].gsub!('\'', '\'\''); row[2].gsub!('\'', '\'\''); row[3].gsub!('\'', '\'\''); puts \"INSERT INTO chartulas VALUES (DEFAULT, 1, \'#{row[1]}\', \'#{row[2]}\', \'#{row[3]}\', \'#{row[4]}\', \'#{row[5]}\');\"; end" /tmp/chartulas.

13 Aug 2024

20240813

「コード読めばわかるんで」という人は危険人物 New Type Pattern の記事を読んでいて、思わず膝を打ってしまった。 経験から「コード読めばわかるんで」という人は brilliant jerk 気質の人に多い気がする。 When asked what their test function tests, this teammate might tell you, "just read the code". This individual is dangerous, and should be treated with the same fear and suspicion you reserve for C++. https://www.howtocodeit.com/articles/ultimate-guide-rust-newtypes 戦わずして勝つ、ではないけど、コードを読まずしてドキュメントや図でわかるんだったらなおさらいい。

8 Aug 2024

20240808

beta 0.5 でするグラウンドワークに rubocop を入れる ちょうどよい記事を見つけたので beta 0.5 の作業に入れておく。 継続的にRailsアプリを開発する上で早めにやっておきたいこと 開発の標準プロセスを最初に整備しておくと恩恵が大きい。逆に最初が「ぐだぐだ」だと後から軌道修正するのは難しい。 その意味でも最初の設計やワークフローの整備は経験のあるエンジニアが行うべきだと思う。 次からは 2 回目になります 「まずは 1 回やってみてください。次からは 2 回目になります」は蓋し名言だと思う。ただし、進次郎が言ったわけではない。 物体は摩擦の関係で動き出す時が最もエネルギーを必要とするのと似ている。 「まずは 5 分やってみてください。少なくとも 5 分はやったことになります」だと響かないか。難しいな。 天穂のサクナヒメ アニメを見始めた。なかなかよい。どこがいいのか、説明が難しい不思議な魅力がある。 「やればできる子」のサクナヒメの成長はもちろん、どこか日本の原風景の描写に惹かれるのかもしれない。 異物として外国人のミルテを入れているところは閉鎖的になりがちな日本文化に客観性を導入したのかもしれない。 前から名前だけは聞いていたけど、ゲームもプレイしたくなってきた。

5 Aug 2024

20240805

アルファ版のユーザーのペルソナ 個人開発している Web アプリのアルファ版のユーザーを探している。 コアなユーザーを 10 人、いや 3 人ほど集めたい。 以下に該当する人たちを想定している。 英語の非ネイティブスピーカーで継続的に学習をしている人/仕事で日常的に英語を使用している人 通訳者/翻訳者/研究職/外資系社員/ブリッジエンジニア/留学生/大学生/海外留学希望者/バイリンガルのライター/英英辞典を使っている学習者 具体的なペルソナとしてはこんな人たちだろうか。 私は、語学学習の中では単語力強化にとてもこだわっている。外国語能力(とくに読解力)と語彙力には 高い相関関係があることが実証されており、語彙力を伸ばせば外国語能力も飛躍的に伸びる可能性が高いといえる。 単語は理屈抜きに覚えるしかなく、日本にいながらネイティブの読解力に近づこうと思ったら ただひたすら知らない単語をしらみつぶしに覚えていく努力をするしかない。 ロンドン大学の遠隔教育を受けたとき、課題図書に難易度の高い英単語が頻出しているのに気づき、 ネイティブの若い学生たちがこんな難解なテキストを読んでいることに度肝を抜かれた。 英検1級に合格したことで満足し、語彙力強化を怠ってしまったら、大学の指定図書さえ十分に読めないことを 思い知ったのだ。そしてこのとき私は「一生語彙力を磨き続ける」と強く心に決めた。 ネイティブ並みの語彙力をつけるには、それほどの鍛錬が欠かせないのだ。 <https://serai.jp/hobby/1060906#google_vignette> これは、我々通訳者が作る単語帳です。お見せするのも恥ずかしいんですが(笑)。 これはビル・ゲイツさんの通訳をさせていただいたときの単語帳で、本当に恥ずかしいんですが…… こういうもの(英単語が書き込まれているExcelのシート)を毎回作ります。 私は18年間通訳の仕事をしていますが、すべての英単語を覚えるなんていうことはムリです。 ですから、毎回新しい言葉を覚えていますし、このように単語帳というものを作るんですね。 でも、それでもやっぱり完璧にはなりません。 <https://logmi.jp/business/articles/322640> 橋頭堡としてのファーストアプリ たとえ、誰も使わなかったとしても、自分が使うから開発は継続していく。 少なくとも自分の英語力強化には役立っているという点では価値がある。 また、開発を通して得た経験値も大きい。 認証/決済といった機能やプライバシーポリシー/利用規約などの汎用性が高いパーツについては 今後の開発で共通して使用できる。結果、開発効率が向上する。 インフラ面としては AWS Organizations + IAM Identity Center の運用の道筋が見えたことや 開発/ステージング環境として fly.io へのデプロイするノウハウが得られた。 個人開発は超ニッチで勝負し、売上を目指さない 「エンジニアが開発したアプリは自己満足で自分だけが使うアプリになってしまう」類のことを 耳にすることがあるが、それでいいのではないだろうか。少なくとも、ひとり、自分というユーザーの 問題を解決できているのであれば、それだけで価値がある。そのエンジニアの感覚がよほど他者と かけ離れていない限り擦り合わせるのはそんなに難しくはないはずだ。 git もこういったアプローチのもと作られたと認識している。 振り返ってみると、こんな超難解なツールがよく流行ったものだと思うが、根本的な問題を解決しているのであれば 多少使い方やインターフェイスが独特だろうが一般化はしやすい。 個人開発のもうひとつのよいところは売上を目指さなくていいということだ。 これは、ターゲットとなるユーザーを選べる、と言えるかもしれない。 「この問題に対する私の解はこうだけど、よかったらあなたも使って」的なアプローチは OSS の基本だ。 無理に大衆に迎合したプロダクトを作ることは強みを希釈することにつながる。 最後に、売上の必需性。例えば売上が1万5,000円とか。50万円という額は僕らからするとすごく高いですよね。 良いなって思います。けれども、スタートアップからすると、50万円じゃ会社が成り立たないですよね。 ということで、じゃあ個人開発者がどうやって生きたらいいかなんですが、つまり売上がそこまで高くない、 リスクがある分野には、ライバルがまず少ないと思っています。 https://logmi.jp/tech/articles/330120

2 Aug 2024

20240802

歩くことが大事 このごろは、暑いのと開発に時間を割いているのとで、朝の散歩が疎かになっていた。 そのせいか、体重が増加傾向になってしまった。 日光を浴びるという点でも、忙しくても散歩はするようにしよう。 歩きながらいろいろ思考の整理もできるし。 何気に shuttle.rs にデプロイしている statscribe が記録用に役立っている。 普段使いする API はこういうのでいいんだよ、こういうので。 $ xhs get -b statscribe.shuttleapp.rs/stats/${token}/all | jq -cr '.[] | select(.tag == "scale")' {"id":1,"stat":77.4,"tag":"scale","datetime":"2024-07-01T09:05:40.845351+09:00"} {"id":9,"stat":77.2,"tag":"scale","datetime":"2024-07-02T03:51:50.376971+09:00"} {"id":10,"stat":76.7,"tag":"scale","datetime":"2024-07-03T03:28:54.172793+09:00"} {"id":16,"stat":76.2,"tag":"scale","datetime":"2024-07-04T05:12:43.866092+09:00"} {"id":17,"stat":77.2,"tag":"scale","datetime":"2024-07-05T04:44:45.235495+09:00"} {"id":18,"stat":78,"tag":"scale","datetime":"2024-07-06T04:42:20.911373+09:00"} {"id":20,"stat":78.3,"tag":"scale","datetime":"2024-07-07T03:37:12.576454+09:00"} {"id":21,"stat":78.3,"tag":"scale","datetime":"2024-07-07T09:01:28.056666+09:00"} {"id":22,"stat":78,"tag":"scale","datetime":"2024-07-08T04:54:09.465264+09:00"} {"id":23,"stat":77,"tag":"scale","datetime":"2024-07-09T05:22:51.127532+09:00"} {"id":24,"stat":76.4,"tag":"scale","datetime":"2024-07-10T05:04:37.611616+09:00"} {"id":25,"stat":77,"tag":"scale","datetime":"2024-07-11T04:43:52.913890+09:00"} {"id":26,"stat":78.1,"tag":"scale","datetime":"2024-07-12T05:35:25.985414+09:00"} {"id":27,"stat":77.4,"tag":"scale","datetime":"2024-07-13T04:59:01.999598+09:00"} {"id":28,"stat":77.7,"tag":"scale","datetime":"2024-07-14T04:23:18.075916+09:00"} {"id":29,"stat":77.1,"tag":"scale","datetime":"2024-07-15T06:11:50.229005+09:00"} {"id":30,"stat":76.9,"tag":"scale","datetime":"2024-07-16T06:45:28.790132+09:00"} {"id":31,"stat":77.7,"tag":"scale","datetime":"2024-07-17T05:46:38.295156+09:00"} {"id":32,"stat":76.7,"tag":"scale","datetime":"2024-07-18T07:10:00.187350+09:00"} {"id":33,"stat":77.3,"tag":"scale","datetime":"2024-07-19T05:11:34.686213+09:00"} {"id":34,"stat":76.7,"tag":"scale","datetime":"2024-07-20T07:08:06.165706+09:00"} {"id":35,"stat":77.6,"tag":"scale","datetime":"2024-07-21T04:01:30.638578+09:00"} {"id":36,"stat":78,"tag":"scale","datetime":"2024-07-23T06:06:49.346260+09:00"} {"id":37,"stat":77.7,"tag":"scale","datetime":"2024-07-24T04:01:44.228581+09:00"} {"id":38,"stat":77.7,"tag":"scale","datetime":"2024-07-25T04:49:49.478899+09:00"} {"id":39,"stat":78.2,"tag":"scale","datetime":"2024-07-26T06:07:19.482083+09:00"} {"id":40,"stat":78.4,"tag":"scale","datetime":"2024-07-29T05:50:16.527464+09:00"} {"id":41,"stat":78.8,"tag":"scale","datetime":"2024-07-30T04:06:31.847886+09:00"} {"id":42,"stat":78.5,"tag":"scale","datetime":"2024-07-31T06:14:20.245091+09:00"} {"id":43,"stat":78.3,"tag":"scale","datetime":"2024-08-01T05:34:16.283147+09:00"}

30 Jul 2024

20240730

タップでトグルされる KPI fitbit をタップすると現在日時が 2339 30日 火 のように表示される。 最近のアップデートでさらにこの下の 1 行に消費カロリー、歩数、心拍数が表示されることに気がついた。 タップごとに絵文字と数字の組み合わせが切り替わるようになっている。これはよい UI。 ❤️65 → 👞 12,845 → 🔥 2813 継続の指標となる数字をさりげなく表示するという点は個人開発にも活かしたい。 とりあえず開発中のアプリのロゴの右に単語数を表示するようにしてみた。 screenshot of rails app logo

28 Jul 2024

20240728

Postgresql では auto_increment が効かない rails db:reset && rails db:migrate してから Model.create() すると id が入るけど、 既存のデータをリストアすると id が nil になってしまう問題に悩まされている。 これでもダメ。 def change remove_column :mytables, :id add_column :mytables, :id, :integer, primary_key: true, null: false, autoincrement: true end この例を参考に .maximum(:id).next.to_i したらリストアしてからも id が入るようになったけど こんなんが本当に必要なのか? auto increment は MySQL の方言とかいう人もいるし。もう少し調べてみるか。 https://stackoverflow.com/questions/40545281/autoincrement-postgre-db-id-field-in-rails

27 Jul 2024

20240727

PostgreSQL のダンプデータからテーブル名を別名にしてリストアする 既存の Rails アプリをいちから作り直しているうちに、だいぶ形になってきた。 すでにデータは既存のアプリにあるので、そちらからテーブル名を別名にしてリストアする方法を探していたが、以下に落ち着いた。 既存のテーブル名を sources 新規のテーブル名を destinations とする場合、一度別名でテーブルのコピーを作成する。 その後ダンプしてリストア時に別名にしたテーブルを指定すればよい。 > CREATE TABLE destinations AS SELECT * FROM sources; ➜ pg_dump -f db/development.dump.bin.postgres ${db} -Fc ➜ pg_restore -c -U rails -W -d [PROJECT_NAME]_development -t destinations development.dump.bin.postgres

25 Jul 2024

20240725

さようなら dotenv, こんにちは Encrypted credentials The Complete Guide to Ruby on Rails Encrypted Credentials を読んで 認証情報の保存場所を .env から config/credentials/development.yml.enc に切り替えた。 Rails における認証情報の取り扱いの新標準だと思う。 この変更により rails アプリから認証情報を参照する方法も変わることになる。 screenshot of diff 同時にマスターキーも config/credentials/development.key になる。 これにより既存の config/credentials.yml.enc と config/master.key は不要になるので削除してしまってよい。環境ごとの認証情報と鍵は以下のコマンドで生成できる。 ➜ EDITOR="vi" rails credentials:edit --environment=development これで dotenv とさよならできるかと思ったが、AWS SDK にホームディレクトリ配下 .aws/{config,credentials} の認証情報を読みにいかせないための AWS_SDK_CONFIG_OPT_OUT だけは必要になる。これだけなら認証情報でもなんでもない。いままでは .gitignore でコミットしないとはいえ .env に平文で書かれていた認証情報が気になったが今後はそういう こともなくなるので精神衛生上もよい。 ➜ cat .env AWS_SDK_CONFIG_OPT_OUT=true 新旧を比較すると以下のようになる。development.yml.enc と development.key は環境ごとに staging や production と読み替えることが可能。 いままで これから 提供元 rubygem: dotenv rails 標準機能 認証情報の格納ファイル .

24 Jul 2024

20240724

FIXME with types 個人開発では割と「緩い(loose)」コミットを許容している。 仕事だともう少し推敲したりするようなところでも FIXME コメントとともにコミットしてしまうことが多いが 個人開発は継続性に重点をおいてこのようなスタイルにしている。Conventional Commits ならぬ Conventional FIXME と言えるかもしれない。 そんな感じでコミットを重ねていくと自然と FIXME が増えていくことになるが、そのうち FIXME もいくつかの種類に分類できることに気がついた。 Conventional Commits 同様、FIXME にも「型」を導入すると理解や検索の 点でよいかもしれない。 screenshot of rails error message 現在、思いつくのはざっと以下の通り。HANDLE ERRORS, O11Y(Observability), NEED TEST は機能が 一通り整ってから取り掛かるなど自分なりの開発方針を立てると、完璧主義の罠にも陥らずにすむし nitpicker にもならずにすむ。 WRITE BETTER HARD CODING SENSITIVE DATA PERFORMANCE UGLY APPEARANCE NEED MORE NOT WORK HANDLE ERRORS O11Y NEED TEST Rails にはサブコマンドの notes があるが、単純に FIXME の文字列で検索して表示しているわけではないようだ。 $ bin/rails --help | grep notes notes Show comments in your code annotated with FIXME, OPTIMIZE, and TODO $ bin/rails notes app/controllers/auth_controller.

23 Jul 2024

20240723

暗黙の優先順位 Cognito のためにクライアントを作成する時に dotenv を使用して 認証情報を Rails アプリに ロードしているのにそちらを使わずに aws configure sso の値を使っているために IAM Identity Center(sso) のセッションが切れると Aws::Errors::InvalidSSOToken になってしまっていた。 screenshot of rails error message これは AWS SDK が認証情報を参照する優先順位として、まずホームディレクトリにある ~/.aws/{config,credentials} を 優先してチェックしてしまうからだった。AWS_SDK_CONFIG_OPT_OUT=true にしておけばこの問題は解決する。 fly.io では発生しないだろうし、こういう環境依存の問題が最もわかりにくい。 The shared config file is not checked if the environment variable AWS_SDK_CONFIG_OPT_OUT is set. https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html

22 Jul 2024

20240722

どの Web サービスにも必要な 2 つの機能 認証と決済。以前からこの 2 つの機能を自分で作れるようになりたいと考えていた。 この 2 つは一度作ってしまえば、ほぼ全ての Web サービスで使いまわせるので投資対効果が高い。 多産多死で打率1割どころか3厘(「せんみつ」と呼ばれる)ぐらいの新規事業で真っ先に共通化したい部分だと思う。

21 Jul 2024

20240721

AWS Cognito Hosted UI 個人開発しているアプリの認証基盤に AWS Cognito を使用するため、土日に弄んでいた。 最初は SDK 経由での実装を試みていたが、ネット上にあまり例が見つからないのと、手順が煩雑な印象を受けていて諦めそうになっていたところ、 YouTube の動画で Hosted UI の機能を知った。 フォーム自体を AWS が生成してくれるのでアプリが acc/pass を全く触ることなく認証を完了できるのがよい。 Hosted UI でコールバックされた後にどうすればいいのかが不明だったが AWS 公式ブログのこの記事の Authorization code grant の通りにやってみたら 無事にユーザープールにアクセスすることができた。Rails アプリとしては UUID で管理されているユーザー ID を Users テーブルに格納するだけでよい。 個人開発者にとって 認証基盤など個人では手に負えない分野は巨大テックの企業努力を利用させてもらう のが正しいアプローチだと思う。 4. After Amazon Cognito verifies the user pool credentials or provider tokens it receives, the user is redirected to the URL that was specified in the original redirect_uri query parameter.

19 Jul 2024

20240719

Linux の man セクションの分類方法を転用する Warp の notebook にコマンドの snippet などをナレッジとして少しずつ書き足していくうちに次第に煩雑になってきた。 どうやって整理したものかと考えたところ、Linux の man ページに倣って独自に 1 から 9 のそれぞれの数字にカテゴリを定義し、 分類していくことにした。 0 から 9 の数字に種類としての意味を持たせて分類するやりかたは図書分類法に代表される歴史的な方法だが、人間が処理することを想定しているはず。 コンピュータにはまた別のやりかた(10進数ベースではなく2進数ベース)もありそう。 ただ、Warp を操作するのは人間である自分だからなぁ。 3. Framework Manual には rails や hugo 関連を、4. Saas Manual には AWS 関連(CLI, SDK, Cloud Formation) をはじめ fly.io や shuttle.rs で提供されている CLI を 含めていく。 自分のナレッジとしてのセクション 1. General Commands Manual 2. Programming Manual 3. Framework Manual 4. SaaS Manual 5. Formats Manual 6. Project Manual 7.

18 Jul 2024

20240718

自由度の高さが心地よい Hugo シンプルかつ拡張可能な設計が素晴らしい。プログラマ向けの静的サイトジェネレータといったところ。 Template と Method を少し触った程度だが自由度の高さが心地よい。 ブラウザからではなく生のファイルに対して grep をはじめ *NIX 環境のツールが使用可能な状態にしておくのは 検索、置換、といった編集上でも、バックアップといった運用上でも恩恵が大きい。 とりあえずランディングページにコンテンツを連続して表示するようにしてみた。 コンテンツごとの区切りがわかりやすいようにインラインで色づけしている。 layouts/_default/home.html {{ define "main" }} {{ range where $.Site.RegularPages "Section" "posts" }} <h3 style="background: linear-gradient(to right, #33ccff, #66ccff, #ccccff, #ffccff); -webkit-text-fill-color: transparent; -webkit-background-clip: text;"> {{ .Title }} </h3> {{ .Content }} <p style="text-align: right">{{ .Date }}</p> <hr/> {{ end }} {{ end }} Multilingual mode の設定もしてみた。 選択可能なオプションとして Translation by file name と Translation by content directory があるが後者を選択している。 どちらを選んでも設定した言語でパス依存の自動リンクが生成される。 せっかくなので 日本語 の時はダークモード、 英語 の時はライトモードにした。 このマルチリンガル設定は通訳者や翻訳者の学習プロセスにも使用できるのではないだろうか。 まだ未対応の有用な設定項目もあるのでいろいろ試したい。.