TECH PLAY

ニフティ株式会社

ニフティ株式会社 の技術ブログ

517

インターネットの世界では、サイバー攻撃をはじめとする新たな脅威が次々と生まれています。健全な企業活動を維持するためにも、社内のセキュリティ対策強化は欠かせません。 ニフティにも、社内全体のセキュリティを推進する専門チームがあります。 前編 では、具体的な業務内容やこの仕事の魅力、やりがいについてメンバーに語ってもらいました。後編では、ニフティという会社の良いところ、チームに迎えたいメンバー像、さらには各々が描く今後のキャリアについて伺います。 入社直後から「歓迎されている」と感じられた みなさんが思う「ニフティの良いところ」を教えてください。 Mさん 基本的に、新しく何かを導入したり、挑戦したりといったことに対して前向きな会社だと感じます。たとえば、最近の自チームでいうと新規チームの立ち上げの話やセキュリティシステム内製の話、他チームでも新規のソリューション導入や新規ビジネスなど、マネジメント層含めて前向きに取り組む方が多いですね。 あとは、私は中途入社なのですが、転職活動中に会社のことを調べていたら「ニフティには良い人が多い」という情報がけっこう出てきて。本当かな?と思っていましたが、入社してみたら実際に良い人ばかりで安心しました(笑)。みなさん人当たりがいいし、入社直後は特に積極的に声をかけてくださったり、中途入社組のコミュニティに招待してくださったりと、「歓迎されているな」と感じさせてもらえたのはありがたかったですね。 Tさん 僕も一番に思い浮かぶのは「人」ですね。僕の場合は新卒入社ということもあって、会社勤め自体が初めてという不安な状態のなかで、親身になって相談に乗ってくれる先輩がたくさんいました。おかげさまで社会人のスタートとしては、すごく良い入り方ができたと思います。 Mさんも言ってくれた挑戦という部分でいうと、個人のやりたいことも尊重してくれる会社だと感じます。定期的に上司との1on1の面談機会があって、将来的にやりたいこと、目指したいことを相談できるんです。その時すぐに実現するのは難しいことでも、先を見越して「じゃあ、今のうちにこういう経験を積むといいんじゃない?」と前向きな提案をしてくれるので未来も描けるし、日々の業務へのモチベーションも上がりますね。 Hさんは入社6年目と、2人よりも長くニフティに勤めていますが、どんなところに良さを感じますか? Hさん 二人に先に言われてしまいましたが、チャレンジしやすい環境はニフティの大きな特徴です。個人でいうと、たとえば何か学びたいこと、伸ばしたいスキルがあるとして、目的が明確であれば会社がそれをサポートする環境を用意してくれます。学んだことを生かして活躍できる場も多いと感じますし、成長の機会が至るところにある会社なのではないかと思います。 辛抱強く、丁寧に対応する姿勢が求められるセキュリティの仕事 現在、セキュリティチームは3名ということですが、これからさらに人手が必要になると思います。新しいメンバーを迎えるとしたら、どんな人がいいですか? 望ましいスキルや人物像を教えてください。 Hさん セキュリティチームの業務の一つに、社内各部署からのセキュリティに関する相談対応があります。そうした様々な困りごとに対して、真摯に取り組めるかどうかが、まずは大事な素養になると思います。たとえば、セキュリティ観点から見れば懸念がある相談ごとに対して「NO」と言うのは簡単ですが、できればそれを実現させる方法がないかを辛抱強く考えていく。そういった思考を持てるかどうかは重要です。 また、言われたことだけをやるのではなく、自身の興味に従って主体的に学べる人、動ける人も大歓迎です。TさんやMさんがまさにそうなのですが、二人とも新しい技術を学ぶことに対して貪欲で、各々が外で吸収してきたものを本業にフィードバックしてくれています。セキュリティの世界に限ったことではないかもしれませんが、その時々で押さえておくべき知識やスキルはどんどん変わっていきますので、自ら学ぶ姿勢がある人ほど活躍し続けられるのではないでしょうか。 最近でいえば、生成AIなどもその一つですね。 Hさん 社内でも今まさにAIを推進するチームが立ち上がっていますが、当然、セキュリティの観点で押さえておかなければいけないポイントもたくさんあります。ただ、そこでセキュリティが前面に出ていくと動きが鈍化してしまうかもしれませんので、良いタイミングでセキュリティについて評価する機会をつくるなど、うまく関わっていけたらと考えています。 分かりました。Tさんはいかがでしょうか?どんな人と一緒に働きたいですか? Tさん Hさんがおっしゃったように、何事に対しても辛抱強く、丁寧に対応できることは重要だと思います。たとえば、それまで社内で普通に使われていたツールであったとしても、セキュリティ上の問題が発生すれば利用停止にする判断を下さなければいけないケースもあります。当然、各部署からすれば不便になるとあって苦情が出ることもありますが、その一つひとつに真摯に向き合い、丁寧に説明して納得してもらうことが大事です。そこでコミュニケーションを怠らない人は、この仕事に適していると思います。 また、個人的には技術への関心が高い人に来てもらいたいです。僕自身も今後は技術を身につけていきたいと思っていますので、すでに技術に明るく引っ張ってくれる人、あるいは一緒に成長していける人がいてくれるとありがたいですね。 高まり続けるセキュリティリスクに対し、万全の体制を築いていく みなさんの今後のキャリアの展望や、挑戦してみたいことを教えていただきたいです。Mさんは社外のセキュリティに関わる女性たちと一緒に、キャリアについて考えるコミュニティを立ち上げ活動しているということですが、そこでロールモデルになるような出会いはありましたか? Mさん そうですね。そのコミュニティにはセキュリティの専門家としてキャリアを積んでおられる女性が複数いて、自分自身の今後を考えるうえでもありがたい交流をさせてもらっています。ロールモデルといっても、本当に多様な考え方、様々な道を歩んでいる方がいるので、今はまだ「こうあるべき」みたいに考える必要はないのかなと。あまり固定観念に捉われず、色んな先輩方のお話を伺いながら模索していきたいですね。ただ、いずれにせよセキュリティの仕事はずっと続けていきたいと思っています。 Tさん 僕は先ほども言った通り、当面は技術を身につけていきたいという目標を持っており、攻撃者目線で社内のセキュリティ向上を図れるようなポジションになれたらと考えています。その先についてはまだ深く考えられていませんが、今やりたいことを一つずつ実現しながら、次に目指す道を見つけていけたらいいですね。 Hさんはいかがでしょうか? 個人的な今後の展望を教えてください。 Hさん 私自身は入社以来ずっと、情報セキュリティの部署でやってきました。じつは、社内にセキュリティ1本でやってきた人のモデルはあまりなくて、これからどうキャリアを作っていくかは模索中です。 ただ、基本的にはマネジメント側に回る方向性で考えていて、この少人数のチームで400人の従業員を抱える会社のセキュリティをいかに強固なものにしていくか。今後もさらに高まり続けるセキュリティリスクに対して、いかに万全な体制を構築できるかといった点を突き詰めていきたいと思っています。 前編もご覧ください! 今回はニフティのセキュリティチームのインタビュー(後編)の様子をお届けしました。前編の記事はこちらをご覧ください。 【インタビュー】サイバー攻撃などの脅威から会社を守る。セキュリティチームの仕事とは?【ニフティ セキュリティチーム前編】 このインタビューに関する求人情報 /ブログ記事 ニフティ株式会社 求人情報
はじめに 例年新人向けに2泊3日のエンジニアハッカソンを行っている弊社ですが、今年は新たな試みとして中堅層向けの1泊2日の弾丸日程でのエンジニアハッカソンを実施いたしました。 その時の様子についてお伝えできればと思います。 エンジニアハッカソンのテーマ 未来のNIFTYを創る – 新サービス創出ハッカソン 概要 日程:9/11(木) – 9/12(金) 場所:ハートピア熱海( https://www.h-atami.com/ ) 内容:中堅層向けのAI駆動開発ハッカソン 人数:16人 スケジュール(当初の予定) ■ 1 日目 10:00 熱海駅集合 10:30 チェックイン 11:00 昼食 12:00 開発 18:00 夕食・入浴 20:00 開発 ■ 2 日目 7:30 朝食 9:00 開発 12:00 昼食 13:00 開発 16:30 片付け 17:00 現地解散 事前準備 エンジニアハッカソン当日を迎えるにあたり、以下を行っています。 顧客課題発掘ワークショップ AI活用講習会(全5回) 事前ワーク(全1回) アイデアソン(全2回) 顧客課題発掘ワークショップ 弊社の新規事業立ち上げをリードする樋沼さんにご協力いただき、事業創出のイロハをリーンキャンパスの作成を行いながらご教示いただきました! 普段とは違う、企画側の視点でプロダクトを考えるとても貴重な経験になりました。 通常業務でもここで学んだマインドを活かせる、貴重な講習会だったと思います。 AI活用講習会 社内一のAIマエストロである石川さんにご協力いただき、KiroやClaude Codeについて学びました。 MCPサーバの建て方や、スペックの利用方法という基礎からみっちり叩き込んでいただきました。 社内で各自キャッチアップを行なっていたAIを用いた開発ですが、集中して体系的に学ぶ機会ができてかなり好評をいただいた講習会になりました。 Kiro 参考: https://kiro.dev/ Claude Code 参考: https://docs.claude.com/en/home 事前ワーク 顧客課題発掘ワークショップでのリーンキャンパスを基に、よりエンジニアハッカソらしいサービスやプロダクトを考えるブラッシュアップの時間です。 ここで練られたリーンキャンバス/アイディアを基に、エンジニアハッカソ当日のチームを決定しました。 アイディアソン 全2回のアイディアソンでは、チームごとに別れての作業でした。 チームは1チーム3人で、5チームになりました。 それとは別に6チーム目として、AI活用講習会の講師を務めた石川さんが1人チームとして参戦となりました。 アイディアのブラッシュアップを行ったり、 使用技術の選定や、チーム単位のAI駆動開発を行う上での、進め方の検討など細かい調整を行いました。 全2回以外にも、チームの認識合わせなどは自由に行なって良いことになっていたので各チームとも積極的に集まって準備を行なっていました。 今回は、AIを用いた1から立ち上げるプロダクトの開発を2日で完了させなくてはならない関係上、かなり綿密に計画を練っていました。 チームによっては、エンジニアハッカソに向けてAIの特性を理解するために1つサービスを作り上げて、確認しているチームもありました。 本番 1日目 集合(10:00) 熱海駅に現地集合しました。 集合は10:00でしたが、7:30に到着して海を見に行っていた猛者も…(遅刻するわけにはいかないという責任感のある運営の一人です) 全員無事に集まることができました。 宿への到着とチェックイン 宿のバスに揺られること体感10分。 ものすごく景色の良い宿に到着して、ハッカソン参加者一同から感嘆の声が上がっていました。 昼食(11:00 ~ 12:00) 宿に着いたらまずお昼です! 開発への英気を養います。 開発(12:00) いよいよ開発スタートです! まずはモニターの設置から…。 初日は2部屋に分かれての開発でした。 各チーム、黙々と作業を行っていました。 KiroちゃんとClaude君が大活躍です! 一貫してKiroを利用する人や、Claudeに全掛けする人、タスクごとに分けて利用する人、様々いらっしゃいました。 各チームが何を作成していたのかは今後公開予定の個別のブログでご確認ください 夕食(18:00) 楽しい夕食の時間です! めちゃくちゃ豪華で賞賛の嵐でした。 どれも美味しかったです。 開発で疲れた身体に上質な栄養が行き渡りました。 開発再開(19:30) ちょっと早めに開発再開するチームが多かったです。 初日の開発はどのチームも上限の22:00までガッツリ行っていました。 お疲れ様です! 予定した進捗通りに進んだチームは少なく、みなさん悔しそうな感じでした。 夕食前まで、2部屋に分かれて作業になっていたですが、宿のご厚意により1部屋で作業を行うことになりました。(2部屋に分かれて作業させていただいたのもこちらの我儘を汲んでいただいた、宿のご厚意です) 新しいお部屋は、開発で利用して良い部屋なのか…?と気後れする様な荘厳な感じのお部屋でした。 各自お休み(22:00) お風呂に入ったり、部屋で休んだりと各自次の日に向けて英気を養いました。 2日目 朝食(7:30) ビュッフェ形式で、各自で朝食を取るスタイルでした。 朝食前に、散策したり、朝のお風呂に入っているメンバーもちらほらいました。 中には5:30くらいには入り始めているメンバーも… 開発開始(9:00) 昨日に引き続き、黙々と開発を行っていました。 時折「おー」やパチパチといった歓声や拍手が聞こえてきました。 その度、「あのチームはもうできたのか!?」みたいな焦りが各チームから見られてきました。 終いには、「他のチームにプレッシャーかけるためにとりあえず”おー”とか言っておく?」みたいな周りにプレッシャーを与える戦法もあるのではという疑心暗鬼が生まれるフェーズがありましたが、それ以外は粛々と進んでいたように思います。 昼食(12:00) そろそろ完成の目処が立ってきてもおかしくない頃。 昼食を食べる時間すら惜しむようなチームもありましたが、オセロをしたり卓球をしたりと余裕を見せる人もちらほら。 しらす丼はみなさん喜んで食べていました! 開発再開(13:00) 午後は、佳境を迎えた開発メンバーたちがより一層黙々と作業をしていました。 一部、余裕のあるメンバーはノスタルジー風味のエモい写真を撮ったり、館内の写真を集めたりしていたようですが、それ以外は他チームの歓声に怯える以外は鬼気迫る表情で開発を続ける面々でした。 片付け…?(16:30) 当初予定していた予定では片付けの時間でしたが、ここで延長戦に突入することが急遽決定。 これについては、運営側の落ち度であります。 外部モニターは集荷の関係で片付けてます。 会場の延長利用を快諾くださったハートピア熱海様には感謝しかありません。 開発延長戦(16:30) 最後の力を振り絞って、みなさん頑張っていました! 撤収(18:00) ホテル撤収(18:15) 2日間頑張った参加者で集合写真を撮って、各々帰路につきました。 おわりに 今回、場所の提供をいただいたハートピア熱海様( https://www.h-atami.com/ )には格別のご配慮を賜りましたことを改めてお礼申し上げます。 参加いただいたエンジニアのみなさまにも感謝を申し上げます。 この2日間で得た、知見などは社内に展開して、新たな会社の原動力になるよう業務に励んでいければと思います。
この記事は、 ニフティアドベントカレンダー の9日目の記事です。 はじめに こんにちは!新卒1年目のなべしまです。寒くなってきましたね。 街では華やかなクリスマスツリーが現れる季節になりました。そんな中、私の前に現れたのは複雑な DOMツリー でした。 筆者について 入社: 2025年4月(新卒1年目) 担当業務: カスタマーサポートグループ(ジョブローテ中) コールセンター支援ツールの運用開発業務 TypeScript/JavaScript 開発経験 学生時代の授業にて、少しだけ演習を行った程度 きっかけ 現在担当しているツールでは、開発言語としてTypeScriptを利用しています。業務中、DOMを操作する querySelector メソッドに遭遇しました。 getElementById メソッドは知っていたのですが、両者の違いについて気になり、まとめてみようと思いました。 この記事では、JavaScript/TypeScriptで使えるさまざまなDOM要素取得メソッドの特徴や違いを解説します。知識の整理や新たな学びのきっかけになれば嬉しいです。 事前準備 DOMツリーについて ブラウザは HTML を読み込むと、内部で DOM(Document Object Model) と呼ばれるツリー構造を生成します。DOM は文書をツリー構造で表現し、各ノードがオブジェクトを含みます。DOM のメソッドでツリーにアクセスし、文書構造やスタイル、コンテンツの変更ができます。 DOM は HTML をプログラムで操作するためのデータ構造 です。そして、JavaScript が操作するのはこのツリー内の「ノード(要素)」となります。 document └── <html> ├── <head> └── <body> ├── <div class="profile-card"> │ ├── <h2 id="card-title"> │ ├── <div class="user-info"> │ └── <div class="actions"> └── ... 要素について HTMLElement HTMLのタグ1つ分を表すオブジェクト(例: <div> , <p> , <button> など) HTMLCollection HTMLElementの汎用的な集合(配列風オブジェクト) 動的 であり、DOM の変更が自動的に反映 NodeList ノードのコレクション(配列風オブジェクト) querySelectorAll が返す NodeList は 静的 DOM の変更は反映されない DOM要素を取得する方法 例えば、以下のようなHTMLドキュメントを見てみましょう。ここから、要素を単一で取得したいことを考えます。 <body> <h1 class="main-title">タイトル</h1> <div class="profile-card"> <h2 id="card-title">ユーザプロフィール</h2> <div class="user-info"> <p class="text">名前: なべしま</p> <p class="text">職業: システムエンジニア</p> </div> <div class="actions"> <button class="btn">フォローする</button> </div> </div> </body> 要素取得メソッドの例 idから取得する場合 getElementById でidを指定することでHTMLElementオブジェクトを取得できます。要素が見つからない場合は null を返します。 const title = document.getElementById('card-title'); // 戻り値: HTMLElement | null classから取得する場合 getElementsByClassName でclassを指定することによって、HTMLCollectionオブジェクトを取得できます。このとき、単一要素で取得したい場合は、HTMLCollectionの要素番号を指定する必要があります。 複数のクラス名を指定する場合は、半角スペースで区切ります。 const texts = document.getElementsByClassName('text'); // 戻り値: HTMLCollection // 単一要素を取得する場合 const firstText = texts[0]; // 戻り値: HTMLElement | undefined タグ名から取得する場合 getElementsByTagName でタグ名を指定することによって、HTMLCollectionオブジェクトを取得できます。 getElementsByClassName と同様に、単一要素で取得したい場合は、HTMLCollectionの要素番号を指定する必要があります。 const buttons = document.getElementsByTagName('button'); // 戻り値: HTMLCollection // 単一要素を取得する場合 const firstButton = buttons[0]; // 戻り値: HTMLElement | undefined querySelectorでの要素取得 利用方法 CSSセレクタを利用した要素取得 querySelector では、id、class、タグ名など、CSS セレクタを利用して要素を取得することができます。要素が見つからない場合は null を返します。 // idでの指定 const title = document.querySelector('#card-title'); // classでの指定 const mainTitle = document.querySelector('.main-title'); // タグでの指定 const button = document.querySelector('button'); // 戻り値: HTMLElement | null 複数のCSSセレクタを利用 親要素と子要素の間に半角スペースを入れて指定することで、子孫要素を取得することができます。 const userName = document.querySelector('.user-info .text'); console.log(userName.textContent); // 出力: "名前: なべしま" 検索方式 querySelector メソッドは指定されたセレクタに一致する、ドキュメント内の 最初の HTMLElementを返します。 直前の例のような式では、「名前: なべしま」を含むDOM要素は取得できますが、「職業:システムエンジニア」が含まれるDOM要素を取得したい場合は、2番目の要素を取得する必要があります。 // 2番目の.text要素を取得する場合 const allTexts = document.querySelectorAll('.text'); const jobInfo = allTexts[1]; // 「職業: システムエンジニア」 複数の要素を取得する場合 querySelectorAll を使用すると、一致するすべての要素を NodeList として取得できます。 const allTexts = document.querySelectorAll('.text'); // 戻り値: NodeList // forEach で反復処理が可能 allTexts.forEach(text => { console.log(text.textContent); }); まとめ 今回登場した、DOM要素取得のメソッドを表にまとめます。 メソッド 戻り値の型 特徴 getElementById HTMLElement | null IDで単一要素を取得 getElementsByClassName HTMLCollection クラス名で複数要素を取得(ライブコレクション) getElementsByTagName HTMLCollection タグ名で複数要素を取得(ライブコレクション) querySelector HTMLElement | null CSSセレクタで最初の要素を取得 querySelectorAll NodeList CSSセレクタで全ての要素を取得(静的) 実務では便利な querySelector を利用しましたが、その他のDOM要素取得メソッドの特徴や戻り値の型の違いを知り、学びになりました。 今回の学びを、今後のDOM操作の実装や、思い通りに動かない時のエラー究明に役立てていきたいです。 参考文献 MDN Web Docs – Document Object Model (DOM) MDN Web Docs – Document.querySelector() MDN Web Docs – Document.getElementById()  
はじめまして。2024年にニフティに入社しました、城山と申します。 本エントリでは、全くの異業種からIT業界へ飛び込んだ私の経緯や、現在取り組んでいる技術的な業務内容、そして会社の雰囲気についてお話しさせていただきます。 これまでのキャリア:物流の世界から 入社前は、主に倉庫系・物流関連の作業に従事していました。日々体を動かし、モノの流れを支える現場で働いていましたが、IT業界への興味はずっと持ち続けていました。 転職のきっかけ:8年来のゲーム仲間との縁 転職の大きなきっかけとなったのは、友人からの紹介です。 この友人とは8年前にゲームを通じて知り合いました。地元が近かったこともあり、長く交流が続いていました。 「新しいことに挑戦したい」「元々興味のあったITの世界に飛び込んでみたい」という相談をする中で、彼が働いている当社を紹介してもらい、このチャンスを掴むことを決意しました。 現在の業務内容:監視業務と自動化への挑戦 現在は主にサーバー・サービスの監視業務を担当しています。それに加え、業務効率化のための自動化にも積極的に取り組んでいます。 具体的な取り組みとしましては、サーバー監視ツールなどを活用し、会社のサーバー不具合検知や監視を行っています。また、日々の定形業務を効率化するため、GAS (Google Apps Script) を活用した業務の自動化を行っています。 業務の自動化では、1時間ごとの定期タスクの自動化や、エラー発生時にSlackへ自動通知するボットの構築などをしました。 未経験からのスタートですが、実際にコードを書いて業務が楽になる瞬間は非常にやりがいを感じます。 入社後の印象:フラットで繋がりやすい組織 入社して一番驚いたのは、組織文化が予想以上にフラットだということです。 メンバー間の関係が非常に良好で、ギスギスした雰囲気は全くありません。わからないことも聞きやすく、心理的安全性が高いと感じています。 他チームとの連携もSlackを通じて、セキュリティチームやPF(プラットフォーム)チームなど、部署の垣根を超えた連携が日常的に行われています。オープンなコミュニケーションのおかげで、スムーズに業務が進められています。 今後の目標:技術の幅を広げたい 正直なところ、エンジニアとしての知識はまだ十分ではありません。しかし、だからこそ「もっと深く知りたい」という意欲が湧いています。 現在はGASをメインで使用していますが、今後はPythonなどを使えるよう他のプログラミング言語も習得し、対応できるスキルの幅を広げていきたいと考えています。 最後に:未経験でも安心できる環境 ニフティは、経験の有無に関わらず「やりたい」と声を上げれば任せてもらえる環境があります。 私のように全くの未経験であっても、基礎から丁寧に教えてくれる先輩たちがいます。 「ITに興味はあるけれど経験がない」という方でも、やる気さえあれば必ず成長できる場所です。興味がある方は、ぜひ応募してみてください。一緒に働ける日を楽しみにしています。
インターネットの世界では、サイバー攻撃をはじめとする新たな脅威が次々と生まれています。健全な企業活動を維持するためにも、社内のセキュリティ対策強化は欠かせません。 ニフティにも、社内全体のセキュリティを推進する専門チームがあります。会社にとって、ある意味「守りの要」であるメンバーはどんな意識で、また、どんなやりがいを持って仕事をしているのでしょうか?セキュリティチームのメンバーに話を聞きました。   自己紹介 Hさん(チームリーダー) 2019年4月入社。メイン業務はISMS(情報セキュリティマネジメントシステム)の推進、インシデント対応、社内セキュリティ対策の企画・運用。趣味はパズルや謎解き。   Tさん 2024年4月入社。メイン業務はISMSの推進、インシデント対応、社内セキュリティ対策の企画・運用。趣味はInstagramで見つけた美味しそうなお店巡り。   Mさん 2024年9月入社。メイン業務はISMSの推進、インシデント対応、社内セキュリティ対策の企画・運用。趣味は都内散策での美術館やカフェ巡り。   社内全体のセキュリティを推進し、インシデントに素早く対応 みなさんはニフティの「セキュリティチーム」のメンバーということですが、まずはチームリーダーであるHさんに、具体的な業務内容をお伺いしたいです。 Hさん メインの業務はISMS(情報セキュリティマネジメントシステム)と呼ばれる、情報セキュリティを管理するフレームワークに沿って規格・ルールの設定、改善などを行い、社内全体のセキュリティを推進していくことです。 また、ニフティとして新規サービスをリリースする際や各部署で新しいツールなどを導入する際に、リスクを判断するようなこともやっています。たとえば新規サービスの導入の際にセキュリティ対策が十分かどうか、リリース後に外部からの攻撃に対する脆弱性はどうかといった点を、ツールを使って評価する役割です。 社内のセキュリティに関して、重大な責任を担っていると。 Hさん そうですね。年に1度、ISMSに沿った運用をしているかの内部監査があるのですが、そこで各部署のセキュリティ対策に問題がないかをチェックして、もし不十分な点があれば我々が深く入り込んで改善を行います。 それ以外にも、各部署が日々の業務のなかでセキュリティに関する不備を発見した場合、セキュリティチームにアラートを上げてもらい、私たちが対応します。幸いなことに、これまでは企業活動の根幹に関わるような甚大なインシデントは起きていませんが、サイバー攻撃などのリスクが高まり続けていることをふまえ、何かが起きた時にすぐに対応できるような訓練や体制を整えておくことが大事ですね。 社内に向けて、リスクに対する発信や啓蒙なども行なっていますか? Hさん はい。技術はどんどん新しくなり、同時にリスクも増えていきます。先ほどのサイバー攻撃もそうですし、最近では生成AIですね。ニフティでは業務での生成AIの使用を厳しく制限していませんが、活用する際のリスクについても十分に知っておく必要があると思います。 ただ、それらに対して一人ひとりがキャッチアップを行うのはなかなか難しいので、やはり我々のような専門チームがリスクについて積極的に発信したり、ルールを作ったりしていく必要があると考えています。 社外のネットワークも駆使し、積極的に情報を共有 Tさん、Mさんはともに2024年入社ということですが、セキュリティチームでは現在どのような業務に携わっていますか? Tさん 入社は2024年4月ですが、セキュリティチームに来たのは2025年1月からで、現時点で10か月ほどになります。主な業務内容ですが、メインは社内の脆弱性の管理です。また、社内各部署からのセキュリティに関する相談に対応することもあります。たとえば、「このツールを使っても大丈夫ですか」「社外の人と連絡する時に、このやり方で大丈夫ですか」といった相談などがあって、その都度、リスクを検証しています。 Mさん 私も基本的な業務内容はHさん、Tさんと変わりませんが、社内セキュリティ対策の企画と検証・導入、外部連携活動がメイン業務になっています。 Tさんはセキュリティチームに配属されてまだ1年足らずということですが、これまでに携わってきたなかで特に印象的だった仕事を教えてください。 Tさん とあるセキュリティ対応で、自分主導で進めたプロジェクトがありました。社内で長く使われているファイルサーバーに問題が見つかったのですが、多くの人が活用しているものですので、影響範囲がとても広かったんです。各所への調整などもかなり大変でしたが、何とか旗を振って解消することができたのは自信にもなりましたし、印象深いですね。 Mさんは前職でもセキュリティの業務に従事されていたということですが、前職との違いを感じる部分はありますか? Mさん 違いとしては、OT(運用技術)からIT(情報技術)の範囲に変わったことと、オペレーション主体の業務からガバナンス主体の業務に変わったことです。また、前職はフルリモートに近い働き方でしたが、ニフティは週5出社なので、ちょっとした雑談をはじめ人と対面で直接会話する量が圧倒的に増え、飲み会の頻度も多く、働き方が大きく変わりました。前職ではOT、セキュリティを立ち上げ推進していくプロジェクトの業務に従事していたのですが、ニフティ入社後はOTにとどまらずIT領域にも携わるようになり、自分のなかで一気にやれることが増えた感覚があります。 また、対外的な活動にも積極的に参加する機会に恵まれました。たとえば、ニフティが加盟しているISAC(情報連携組織)ではセキュリティ分野の様々なWGやSiG、TFに参加しています。そのなかで社外のセキュリティに関わる女性たちと一緒に、セキュリティキャリアについて考えるコミュニティを立ち上げ活動したりもしています。社外との連携、外部から情報を得る機会は格段に増えましたね。 そこで得た情報が、本業にもフィードバックされると。 Mさん そうですね。サイバーセキュリティの脅威はニフティに限らず、全ての会社に共通しています。機微な情報は外部へ出ないので、実際にサイバー攻撃を受けた時の被害状況やその時の対応について範囲を限定して共有いただけることで知見を得たり、また攻撃手法や法制度など昨今の情勢についてキャッチアップすることで、それが結果的に自社の対策強化につながります。 リスクがあるからNGではなく、「実現できる方法」を一緒に考える セキュリティの仕事の魅力、やりがいはどんなところにありますか? Tさん セキュリティの業務をやっていると、色んなチームの人たちとコミュケーションをとる機会があります。ネットワークチームや社内ツールを扱うチーム、他にもたくさんありますが、そうした会話のなかから様々な知識を吸収できる点は魅力の一つですね。一つひとつ理解を深めていくうちにニフティがやっている事業の全貌が見えていく感じも楽しいというか、成長できている実感があります。 それに、仮に他部署へ異動になったとしてもセキュリティの知識は無駄になりませんよね。 Tさん そうですね。無駄にならないどころか、どこへ行っても活かせると思います。例えば、開発などの現場では意外とチーム内にセキュリティの専門知識を持った人がいなかったりもするので、そこでしっかりとした規制や基準に則った知見があれば重宝されるはずです。僕自身もそんな人材になりたいですね。 Mさんはいかがでしょうか? セキュリティの仕事のどんなところに魅力、やりがいを感じますか? Mさん 魅力は、社内で取り扱っている全てのドメインを見ることができる点です。もともと私がセキュリティの仕事を選んだ理由にも通じるのですが、好奇心が強く、新しいものを知りたい、色々な技術に触れていたいという人にとっては苦ではない業務ではないかと思います。 ありがとうございます。Hさんはお二人よりも長くセキュリティの仕事に携わっていますが、魅力を教えてください。 Hさん 今のMさんのお話に近いかもしれませんが、まずは新しい知識を得られることです。セキュリティのリスクにつながる新しい情報は常にキャッチアップする必要がありますし、そのためには社外に出て色んな人と会話をしなくてはいけません。そこで新たなつながりが生まれ、自分の世界が広がっていくような充実感があります。 あとはセキュリティというと、どうしても制限をかける役割というか、「これはリスクが高いからやってはいけない」と、ストップをかける仕事というイメージもあると思います。でも、じつはそうとも言い切れないんですよね。 というと? Hさん 例えば社員から新しいツールを導入したいという相談があった時に、リスクがあるからとすぐに否定するのではなく、できる限りそれを実現するための方法を考える。やりたいことに応えるために、一緒に課題をクリアしていく。私自身はそんな姿勢でいたいと考えていますし、社員一人ひとりの主体性を重んじるニフティという会社ならそれができると思っています。 後編に続きます! 今回はニフティのセキュリティチームのインタビュー(前編)の様子をお届けしました。続きは後日公開予定の後編の記事をご覧ください。 ※ ニフティでは安心安全への取り組みを行っています。   詳細はこちらをご覧ください このインタビューに関する求人情報 /ブログ記事 ニフティ株式会社 求人情報
この記事は、 ニフティグループ Advent Calendar 2025 6日目の記事です。 こんにちは。ニフティ株式会社の佐藤です。 カスタマーサポートグループのサポートシステムチームに所属しており、自社コールセンターにて、主にお客様からの電話入電に対応するオペレーターが使用するツールの開発・運用を行っています。 最近、コールセンター関連の社外イベントに参加する機会が多く、そこで頻繁に耳にする”KCS”というワードがあります。 今回はその”KCS”について説明をしていきます。 コールセンターの現場について ニフティでは、お客様からのお問い合わせ対応窓口の運用の内製化することで、お客様の生の声をより確実に収集し、本質的なサービス改善に直結させる取り組みを行っています。 コールセンターでは日々お客様から色んな媒体(電話、メール、チャットボットなど)からお問い合わせが寄せられます。例えば「インターネット機器の設定について聞きたい」や「契約内容を確認したい」など様々です。 オペレーターはこれらの問い合わせに対し、様々なツールを駆使して対応します。特にインターネット回線関連では、自社で内製開発されたツールに加えて、各キャリア様にご提供いただいたいているツールを使用することもあります。 しかし、 オペレーターは多々あるツールの種類や使い方、できることをどうやって学ぶのでしょうか? また、 様々なお問い合わせに対して、どのように対応すればよいのか、どうやって習得するのでしょうか? もちろん実際にお客様対応する前に研修を実施します。馴染みのないインターネット用語や契約関連の難しい言葉もここで知るかもしれません。 ですが、研修期間を長く設けたり、ベテランの講師を長期間研修に専念させるのはコールセンターを運営する側としては少し非効率です。現在多くの企業で人材不足が課題となる中、一刻も早く顧客対応可能な人材を育成することが重要です。 そこで役に立つのが ナレッジ になります。 誰かが付きっきりで見ていなくても良いですし、いろんな情報が漏れなく文字ベースで載っているので、業務の空き時間や電話対応中でも確認することができます。 そこでまた新たな問題が発生します。 ナレッジ内の情報は誰が最新化をしているのでしょうか? ナレッジに全て最新情報が書いてあると言ってもそれを担保しなければならない管理者が必要です。すべてのツールの使い方や用語、対応フローが全て頭に入っているスーパーマン的な人材が各社のコールセンターにいるはずがありません。複数人で管理してもよいですが、更新作業が頻発すると、それだけで1日が終わってしまうこともあるかもしれません。 そこで KCS というフレームワークを紹介します。 KCSとは? KCSは「Knowledge-Centered Service」の略称になります。アメリカの非営利団体「 サービスイノベーションコンソーシアム 」が作成したナレッジの方法論になります。 とても簡単に言うと「オペレーター自身が都度ナレッジの更新を行う仕組み」です。 KCSの根本的な考え方は「問題解決の過程でナレッジを作成し、そのナレッジを組織全体で共有・活用することで、継続的にサービス品質を向上させる」ことにあります。従来の「管理者が作成したマニュアルを参照する」というアプローチから「実務担当者が現場で得た知見を即座にナレッジ化する」というアプローチへの転換が図れます。 https://www.serviceinnovation.org/wp-content/uploads/2023/03/KCS_DoubleLoop922_notitle_TM.jpg これによって、ナレッジの網羅性が向上し、現場で本当に必要な情報が盛り込まれるため、より専門知識を持った上位者へのエスカレーション回数を減らすことができます。 ナレッジの品質を上げるために、オペレーターには下書きを書いてもらって、それを提出、専門知識を持った方が内容確認を行い、承認後に反映されるといったチェックフローも考えられます。 料金改定や契約期間の延長などのシステム的な変更はオペレーターが対応できないので、管理者もしくは対応部署の方が行う必要はあります。 AI時代のコールセンター AIの利活用が多くの企業で取り組まれています。コールセンターも例外ではありません。 例えば、電話をかけて問い合わせ内容を話すとAIが回答してくれたり、WEB上で入力すると、それに対する回答や、参考FAQを出してくれたりします。 これらのAIは最新の情報を学習して回答を生成するため、いかに情報を新しい状態かつ正確に保ち続けるかが、AI活用における重要な課題となります。KCSの導入により、この課題を解決できると考えています。 おわりに 私たちニフティのコールセンターではまだKCSを導入できておらず、様々な角度から検討を進めています。 最後に、最近聞いた言葉で響いたものを紹介します。 「データは資産のはずが、今は負債に近い。”ある”だけでは価値にならない」 コールセンターに限らず、ナレッジを含む様々なデータは大切な企業資産になるので、それをただ溜めておくのではなく、会社全体で活用していければと思っています。 今後もお客様にとってもオペレーターにとっても価値のあるコールセンターの実現に向けて努力していきます。
この記事は、 ニフティグループ Advent Calendar 2025  5日目の記事です。 こんにちは!セキュリティSREチームでOJT中の坂野です! 今回は、7月にプレビュー版としてローンチして以来、長らくウェイトリスト制だったAgentic IDEである「Kiro」について紹介します。 2025年11月17日、ついにKiroの一般提供が開始され、今回のアップデートでは、AWS IAM Identity Center(旧 AWS SSO、以下 AWS IIC)経由でのログインに対応したほか、コンソール上から直接プラン加入が可能になりました。本記事では、これらの新機能についてまとめていきます! AWS IIC経由だと何が嬉しいのか 実際にAWS IIC経由になると何が嬉しいのか、という点ですが、主に以下のポイントが挙げられるのではないでしょうか。特にこれまでのプレビュー版では個別にクレジットカードを登録する必要があったことを踏まえると、組織利用において大きな進歩だと言えます。 組織としてAWS請求に一本化できる チーム単位でのライセンス管理がコンソール上で可能になる 既存のAWS管理アカウントにコストをまとめることができる AWS IIC経由での外部IdPとの連携が可能になる ポリシーの管理が容易になる 登録方法 1. 管理アカウントのセットアップ まず、コンソールからKiroにアクセスし、メールアドレスを使って管理アカウントをセットアップします。 2. プラン選択とユーザー割り当て 次にプランを選択し、ユーザーもしくはグループを検索し、プランを割り当てます。 なお、同一のKiroプロファイル内であれば、1ユーザーに複数のサブスクリプションが割り当てられても、最も高いTierの価格のみが請求される仕様のようです。 割り当て後、Kiroのページに戻りセッティングページへ移動します。そこで表示されている 「IAMアイデンティティセンターリージョン」 と サインインURL を控えておきます。 3. クライアント側の設定 最後に「Sign in with your organization identity」をクリックし、先ほど控えたリージョンとサインインURLを入力します。また、注意点なのですがここに記載されている「Region」はKiro自体のリージョンではなく、AWS IICを有効化しているリージョンです。ここを間違えるとログインできないため注意が必要です。 入力後、「Continue」をクリックすれば、AWS IIC経由でのログイン完了です。 ポリシー、利用状況の管理について 「Kiro profile」という機能により、グループ全体のポリシーを一括制御できるようです(現時点では未検証)。具体的には以下のような項目が管理対象となります。 MCPの使用 月間の制限超過時の動作 Kiroプロンプトやメタデータのログ記録 使用状況の追跡 ユーザーアクティビティに基づく日次レポートの作成 また、AWS IIC経由(Kiro for enterprise)であれば自動的にオプトアウトがされ、管理者が設定を制御するためユーザー個人の判断でデータ共有が有効化されることはありません。しかしながら、Telemetry送信などのIDEレベルでのオプトアウトの設定については、現状ポリシーでは一括制御できず、各個人が手動で設定する必要がある点には注意が必要です。 まとめ これまでは個別のカード登録など導入のハードルがありました。しかしながら、今回のアップデートによって請求の一本化やユーザー管理が非常にスムーズとなり、組織として安全かつ便利に活用できる土台が整ったと言えるのではないでしょうか。開発体験を向上させるツールとして、ぜひこの機会にチームでの導入を検討してみてはいかがでしょうか。 明日は、@hirost00 さんの記事です!お楽しみに!
この記事は ニフティグループ Advent Calendar 2025 および Rust Advent Calendar 2025 シリーズ 1 の 9 日目の記事です。 忙しい方向け Rust でファミコンの ROM を作ろうとしたら想定外に大変だったけど楽しかった、というお話です。 mrustc + cc65 という組み合わせで Rust コードをファミコン用にコンパイルしたかった mrustc が生成した C コードを cc65 でコンパイルするためにひたすら魔改造 本物の libcore も改造しつつコンパイルが通るところまでいって感動 しかし出来上がったバイナリは 32KB の枠に対して 347KB オーバーという衝撃の結果に… リンカ (ld65) を魔改造して不要なシンボルを削ろうとしたが、低レイヤーが分からず撤退 最終的には最小限の libcore を実装し、とりあえず動かすことに成功 紆余曲折ありましたが、とても楽しい冒険でした。 まずファミコンってどんなハード? ファミリーコンピュータ (以下ファミコンと呼びます) は 1983 年に任天堂から発売された家庭用ゲーム機です。海外版の Nintendo Entertainment System という名前から NES とも略されます。今から 40 年以上前のハードウェアですが、スーパーマリオブラザーズやゼルダの伝説など、今なお語り継がれる名作を数多く生み出した伝説的なプラットフォームです。 自分も全く詳しくないのですが、スペックはこんな感じ。 CPU: 8 bit で MOS 6502 ベースの改造版 (Ricoh 2A03) RAM: わずか 2KB ROM: カートリッジによるが、今回は 32KB 程度 画面解像度: 256×240 ピクセル 現代の感覚からすると信じられないほど小さいスペックですが、この制約の中で当時の開発者たちは驚くべき工夫を凝らしてゲームを作っていたのですね…。 なんでやろうと思ったのか ある日 YouTube を見ていたら、Rust でファミコンのエミュレータを作る動画に出会いました。 面白そうなので自分もやってみようと思ったのですが、いやちょっと待てよと。 作ってもエミュレータで動かせるソフトを持っていないんですよね。 だったらそれも Rust で作ってしまえばいいのではないでしょうか? 大昔のファミコンで現代の言語である Rust が動いたらうれしいと思いませんか。 私はうれしい気持ちになったのでやってみることにしました。 そもそも Rust でファミコンは可能なの? アプローチは二通りあると思います。 まずは LLVM ベースのバックエンドを作るなり探すなりして、通常の Rust ツールチェインの上で動かす方法。 もう一つは、何らかの方法で Rust をトランスパイルし、既存の 6502 用のコンパイラでコンパイルする方法です。 まず、既存のツールチェインを探す方法から。通常、新しいプラットフォームを用意するならこちらが正攻法になりそうです。 最初に確認するのは Rust の 公式な Platform Support (Tier 1 〜 3) です。 見ます。ファミコンは含まれていません。そりゃそうだ。 しかし、コミュニティによる素晴らしいプロジェクトがいくつか存在するようです。 まず、 llvm-mos という LLVM バックエンドがあります。 こちらは 6502 系の CPU をターゲットにしており、ファミコンで動作させた事例も紹介されています。 しかもこの リポジトリ 、2 週間前にもコミットがあってちょっとびっくりしました。 Rust は基本的に LLVM をバックエンドにしているので、それさえあれば Rust コードを 6502 系 CPU 向けにコンパイルすることが可能です。 実際、それをベースにした rust-mos というプロジェクトも存在して、Rust ツールチェインの構築までできていそうでした。今回は試していませんが、実用的なレベルの環境を求めるのであればこちらの方が良いような雰囲気があります。 もう一つは、Rust を何らかの言語にトランスパイルしてそこから 6502 用のコンパイラでコンパイルする方法です。 その場合、第一選択肢はコンピュータ界の標準語であるところの C 言語です。 そして、実はこれにちょうど良いプロジェクトが存在していました。 mrustc : Rust → C へのトランスパイラ cc65 : C → 6502 用のコンパイラ 特に cc65 はファミコン用 ROM を作る界隈では有名なようで、日本語での解説やサンプルコード、情報も多数あります。 どちらのアプローチをとるか考えたのですが、後者の方が私にとっては取り組みやすいのではないかと思いました。何かうまく動かないことがあったとしても、C 言語を中間言語にしていれば何が起きているか読めばよいからです。 ということで、今回は mrustc + cc65 の組み合わせで Rust コードをファミコン用にコンパイルすることを目指すことにしました。 Q: でも C 言語経由するのずるくないですか? Rust で書いたって言えるの? A: ずるいと思いました。でも最終 Rust だけ書いて機械的処理だけで動くって考えたら Rust で書いたって言えると思いませんか? 私はそう言い張ります。 mrustc とは mrustc は、rustc をブートストラップすることを目標に C++ で書かれた Rust コンパイラです。 若干話が逸れてしまいますが、公式の Rust コンパイラである rustc 自身は Rust で書かれています。そのため Rust をコンパイルするのには Rust コンパイラが必要です! これは困りました。もしこの世からすべての Rust コンパイラが消滅してしまったら、もう一度 Rust コンパイラを使えるようになるまでには相当な道のりが必要になってしまいます。 ちなみに、その作業をコンパイラのブートストラップと呼ぶらしいです。 そこで mrustc があれば、C++ コンパイラさえあれば Rust コンパイラを再構築できるようになって便利というわけです。 さらに脱線しますが、じゃあ、その gcc やら Linux やらまで一緒に消し飛んだら再構築はできないのでしょうか? これについては live-bootstrap というプロジェクトなどがあって、手で書いた小さい機械語からアセンブラ、 GCC、coreutils などを経て OS を再構築する手順が丁寧に解説されています。これは異世界転生に備えて覚えておくのも良いかもしれません。きっと現代的なコンピュータ環境を再構築できることでしょう。ソースコードが降ってくれば、ですが…。 話を戻しましょう。 そんな mrustc のツールとしての一番の特徴は、あくまでも valid な Rust コードがコンパイルできることを最重要視している、という点です。逆に invalid な Rust コードがうっかりコンパイルできてしまってもあまり気にしません。例えば… ライフタイム検査をしない コンパイルエラーは「本来コンパイルが通るはずのコードなので mrustc のバグである」と考え、診断は丁寧ではない この割り切りは目標がぶれていなくていいなと思いました。そのかわり、コンパイルエラーが発生したときの調査は若干難しいときがありました。 ただ、今回私にとっての何よりの重要ポイントは、mrustc がバイナリではなく C 言語のコードを出力するという点です。 これはおそらく mrustc 自身のコンパイルに C++ を使うので、同じコンパイラで C コードもコンパイルできてブートストラップ上便利という意図なのでしょう。 今回はその特長を生かして高級なトランスパイラとして使わせていただきます。 そして、この C 言語コードを cc65 でコンパイルすることを目指します。 cc65 とは cc65 は、ファミコンに搭載されている MOS 6502 系 CPU をターゲットとした C コンパイラツールチェインです。 Apple II や Commodore PET、そしてもちろんファミコンなど、6502 系 CPU を搭載したハードウェアで動くソフトウェアの開発に広く使われています。 C99 の一部機能に対応しており、コンパイラ (cl65) 、アセンブラ (ca65) 、リンカ (ld65) に加え、ディスアセンブラ (da65) やオブジェクトダンプ (od65) まで何でも一通りツールがそろっています。 また、ファミコン向けのメモリ領域設定が標準で付属しており、ちょっとした標準ライブラリも備えているので、文字を出力するだけの ROM なら本当にすぐに作れてしまいます。 自力で実装しようと思うと CHR ファイルにフォントのビットマップを用意して PPU レジスタを操作して… と大変らしいですが、cc65 のライブラリを使えばなんと cprintf() 関数一発でリッチに画面に文字を出すことができます。 ファミコン開発においては cc65 は定番ツールの一つとなっているようで、特に日本語の解説記事やサンプルコードも豊富に存在します。今回ファミコン初挑戦なのでこれはありがたいです。 C コンパイラの候補としては先ほどの llvm-mos の成果物である clang だけ使わせていただく手もあると思うのですが、今回はそのお手軽さが決め手となり、cc65 を採用することにしました。 頑張って mrustc が出力した C コードをコンパイルできるようになってもらおうと思います。 レギュレーション さて、実際に作業を始める前に、どこまでできたら「成功」とするかのレギュレーションを決めておきます。 Rust だけで書かれたコードに機械的な処理だけを行い、何かしらファミコンエミュレータで動けば OK とします。 cc65 に入っているライブラリ (例えば cprintf() ) は使って良いことにします。 動かしたい部分が動けば OK で、任意の Rust の言語機能が動く必要はありません。 Q: 2 番目と 3 番目、ずるくないですか? A: いやずるいとは思いました。でも低レイヤー分からなすぎて、PPU の初期化とか割り込みとか、アセンブリレベルで手書きするとすごく変なところで沼りそうな予感がしたんです。技術をつけたらいつか再チャレンジするかもしれません。 とはいえ、最終成果物のために自分で書くコードはすべて Rust で、あとは機械的な変換だけで動かすという方針だけは貫きたいと思います。 cc65 と mrustc の動作確認をする さて、まずは cc65 と mrustc がそれぞれちゃんと動くことを確認しておかないと始まりません。 cc65 でファミコン用 ROM を作ってみる cc65 は使うだけならなんと apt でインストールできます。 apt install cc65 まずは試しに “Hello, World!” を表示するプログラムを書いてみましょう。 #include <conio.h> int main(void) { cprintf("hello, world!"); while (1); // 無限ループで終了しないようにする } これを cl65 -t nes hello_world.c でコンパイルすると、あっという間に hello_world という ROM ファイルが生成されます。 もうこれが ROM です。 hello_world.nes という名前にしてエミュレータで実行してみると画面に “Hello, World!” と表示されました。あっけないけど、でもすでにちょっとうれしい。 なお今回、スクリーンショットには MERU という Web 上で動くエミュレータを使わせていただいております。なんとこちらのエミュレータも Rust で書かれているそうです。 mrustc をビルドする 続いて mrustc をダウンロードしてビルドしてみます。 git clone https://github.com/thepowersgang/mrustc cd mrustc make -f minicargo.mk これも驚くほどあっさりとビルドが完了しました。 生成されるのは以下のものです。 mrustc : rustc の代替となるコンパイラ本体 minicargo : cargo の代替となるビルドツール 標準ライブラリのオブジェクトファイル ちなみにこの状態でビルドされたオブジェクトファイルは、ホストマシンの同じ C コンパイラを使って生成されたバイナリです。なのでもうホストマシンで動く Rust プログラムはコンパイルできる状態になっているはずです。試してみましょう。 fn main() { println!("Hello, world!"); } 実行します。 $ mrustc hello.rs && ./hello Hello, world! 問題ないですね。 ちなみにこのとき生成された C コードは 324 行ありました。 軽く眺めてみると、ネームマングリングされた大量の関数、名前が消去された変数名、MIR を彷彿とさせる bb1: , bb2: といったラベル、そして大量の goto 文が見られます。 いかにも機械生成されたコードという感じですが、所々に元の型名などをコメントで残してくれているのが良心的で、意外と読みやすそうです。 ↓ Rust の main() 関数をコンパイルしたと思われる部分 // ::"bin#"::main void ZRG1cD3bin4main0g(void) // -> () { tUNIT rv; struct s_ZRG2cE9core0_0_03fmt9Arguments0g var1; // ::"core-0_0_0"::fmt::Arguments<'static,>/*S*/ struct e_ZRG2cE9core0_0_06option6Option1gBsSG4c_A3fmt2rt2v18Argument0g var2; // ::"core-0_0_0"::option::Option<&'static [::"core-0_0_0"::fmt::rt::v1::Argument/*S*/],>/*E*/ SLICE_PTR var3; // &'static [&'static str] SLICE_PTR var4; // &'static [::"core-0_0_0"::fmt::ArgumentV1<'static,>/*S*/] var3 = make_sliceptr(&ZRG2cD3binB_09FRAGMENTS0g.val, 0x1ull); // _3 = MakeDst(&::"bin#"::#0::FRAGMENTS, 0x1 usize) var4 = make_sliceptr(&ZRG1cD3binF6const00g.val, 0x0ull); // _4 = MakeDst(&::"bin#"::const#0, 0x0 usize) memset(&var2, 0, sizeof(struct e_ZRG2cE9core0_0_06option6Option1gBsSG4c_A3fmt2rt2v18Argument0g )); // _2 = Variant(::"core-0_0_0"::option::Option<&'static [::"core-0_0_0"::fmt::rt::v1::Argument/*S*/],> #0, {}) var1._0 = var3; var1._1 = var2; var1._2 = var4; // _1 = Struct(::"core-0_0_0"::fmt::Arguments<'static,>, {_3, _2, _4}) ZRG3cD8std0_0_02io5stdio7__print0g( var1 ); // ^ Call( _0 = ::"std-0_0_0"::io::stdio::_print<'static,>( _1, ), bb1, bb2) /* ZST assign */ return ; // ^ Return bb2: _Unwind_Resume(); // Diverge } さて、それぞれのツールが動くことは確認できました。 ここからが本番です。 mrustc の吐き出すコードを cc65 でコンパイルする いよいよ mrustc が出力した C コードを cl65 でコンパイルしてみます。 cl65 が対応していないコマンドラインオプションをごまかすラッパースクリプトだけ挟み、それ以外は素の状態でまず試してみます。 早速自分で書いたコードをコンパイルしたいところですが、実は何よりも先にコンパイルしなければならないものがあります。core という crate です。 急に出てきてなんだと思われると思いますが、これは Rust の標準ライブラリの一部です。 Rust の標準ライブラリは、実は以下のような複数の crate によって構成されています。 core : 最小限の言語のコア機能を集めた小さいライブラリ。プリミティブ型のメソッドはもちろん、四則演算 ( Add , Sub , Mul , Div ) や Iterator , Sized といったコンパイラが特別扱いするトレイトの実体もここにある。OS やヒープアロケーションに依存しない、純粋な言語機能だけを提供する。 alloc : メモリアロケーションが必要な機能を提供するライブラリ。 Vec , String , Box などがここに含まれる。OS ほどリッチな機能はないがアロケータくらいなら作れる、という環境で便利。 std : OS 機能を含む、フル機能の標準ライブラリ。ファイル I/O、ネットワーク、スレッドなど、通常のアプリケーション開発で必要な機能がすべて揃っている。 core と alloc の上に作られており、主要な要素を re-export してくれている。そのため、私たちは背後にある core と alloc を意識せず、 std::ops::Add や std::string::String として参照できている。 組み込みプログラミングではリッチな OS サポートがないこともあるので、 #![no_std] というフラグをつけて標準ライブラリを切り離すことが多いと聞きます。 しかし core を外すことは通常ありません。core は Rust が正気を保てる最後のラインであり、これを外すと本当に文字通り何もできなくなってしまいます。そのため、今回も cl65 で core をコンパイルできるところをまず目指す必要があります。 さて、core crate を mrustc でコンパイルして C ファイルを作るところまでは、ホストマシン向けの処理と一緒なので特に問題はありません。果たして libcore.rlib.c という単一の C ファイルが得られました。 問題はここから。このファイルを cl65 はコンパイルできるでしょうか。 ドキドキしながら最初のコンパイルを試してみた結果がこちらです。 --- BUILDING core v0.0.0 (0.0% 1r,0w,12b,0c/13t) > /workspace/mrustc-master/bin/mrustc /workspace/mrustc-master/rustc-1.29.0-src/src/libcore/lib.rs -o output/libcore.rlib -C emit-depfile=output/libcore.rlib.d --cfg debug_assertions -O -L output --crate-name core --crate-type rlib --crate-tag 0_0_0 > output/libcore.rlib_dbg.txt (0.0% 1r,0w,12b,0c/13t): core v0.0.0 /workspace/mrustc-master/rustc-1.29.0-src/src/libcore/slice/mod.rs:1947-1948 warn:0:Unexpected attribute rustc_on_unimplemented on impl /workspace/mrustc-master/rustc-1.29.0-src/src/libcore/slice/mod.rs:1960-1961 warn:0:Unexpected attribute rustc_on_unimplemented on impl output/libcore.rlib.c(9): Error: Include file 'stdatomic.h' not found output/libcore.rlib.c(12): Error: Include file 'math.h' not found output/libcore.rlib.c(22): Error: Identifier expected output/libcore.rlib.c(22): Warning: Implicit 'int' is an obsolete feature output/libcore.rlib.c(22): Error: ';' expected output/libcore.rlib.c(26): Warning: Implicit 'int' is an obsolete feature output/libcore.rlib.c(26): Error: ';' expected output/libcore.rlib.c(27): Warning: Implicit 'int' is an obsolete feature output/libcore.rlib.c(27): Error: ';' expected output/libcore.rlib.c(28): Error: Identifier expected output/libcore.rlib.c(28): Warning: Implicit 'int' is an obsolete feature output/libcore.rlib.c(28): Error: ';' expected output/libcore.rlib.c(28): Warning: Implicit 'int' is an obsolete feature output/libcore.rlib.c(28): Error: ';' expected output/libcore.rlib.c(28): Warning: Implicit 'int' is an obsolete feature output/libcore.rlib.c(28): Error: ')' expected output/libcore.rlib.c(28): Warning: Implicit 'int' return type is an obsolete feature output/libcore.rlib.c(28): Error: '{' expected output/libcore.rlib.c(28): Fatal: Too many errors C Compiler failed to execute - error code 256 … あの、28 行目で諦められたら困ります。mrustc が吐き出した C コードはまだ 28 万行もあるんですけど… まあ最初はそんなものでしょう… cl65 でコンパイルできるようにいじり回す 細かいものは除いて、主な原因は次のような感じです。 特定のコンパイラ (gcc または MSVC) に依存するコードが生成されている。 __builtin_* 系関数とか。 zero-sized array とか。 cl65 が対応している C 標準が若干古い。 C99 のいくらかに対応しているとのことですが、足りないものも多かったです。 簡単なところでは for の中での識別子定義 for (int i = 0; ...) ニッチなのだと designated initializer struct X x = { .member = value } とか。 プリミティブ型が限定されている。 cc65 (6502 CPU) には float, double サポートがありません。 整数型が (u)int32_t までしかありません。 Rust でいうと i64, u64, i128, u128 がサポートできません。 特に u64 は core::any::TypeId で必要になるので避けられないのですが、避けるしかありません。 アドレス空間が 16 bit しかない。 それと関連して、アセンブラ (ca65) が用意するラベル用の領域が合計 16 bit = 32768 個分しか用意されておらず、28 万行というコードベースに耐えられなくてオーバーフローしてしまいました。 ローカル変数領域のサイズが少ない。 メモリが小さいのでローカル変数をたくさん配置するのは無理です。 調査の段階で core::hash の中で計算用に 1024 バイトの配列をとっているコードを発見し驚くなどしました。現代の PC は大富豪ですね。 ほとんどは mrustc のコード生成の修正です。ただ、ラベル上限などはアセンブラ (ca65) やリンカ (ld65) の修正が必須になりますし、float 等のサポートがない問題については core ライブラリ側の修正が必須でした。 とりあえずまず一旦はコンパイルが通るところを目指し、そのために暴挙という暴挙をいとわず魔改造します。 typedef int float; なんて今後書くことはないでしょうね… 試行錯誤の末、なんとか魔改造 cc65 で魔改造 core をコンパイルできるまでには至りました。 ゴールを間近に感じます。 ここからは単純なユーザープログラムをコンパイルできれば良いはずです。最初の C とほぼ同様な、単純なプログラムをコンパイルしてみたところ… #![feature(no_core)] #![no_core] #![no_main] extern "C" { #[no_mangle] fn gotoxy(x: u8, y: u8); #[no_mangle] fn cprintf(fmt: *const u8, ...); } #[start] fn start(_argc: isize, _argv: *const *const u8) -> isize { cprintf(b"hello\0" as *const u8); loop {} } … なんと、以下のようにリンク時にエラーになってしまいました。 ... (中略) ... output/main.c(252): Warning: '__mrustc_op_and_not32' is defined but never used ld65: Warning: /workspace/cc65/cc65-2.19/cfg/nes.cfg(15): Segment 'CODE' overflows memory area 'ROM0' by 356168 bytes ld65: Error: Cannot generate most of the files due to memory area overflow C Compiler failed to execute - error code 256 Process exited with non-zero exit status 1 FAILING COMMAND: /workspace/mrustc-master/bin/mrustc /workspace/rust-hello-nes/main/src/main.rs -o output/main -C emit-depfile=output/main.d --cfg debug_assertions -O -L output -L output/host --crate-name main --crate-type bin --crate-tag 0_1_0 --target ./target.toml --extern core=output/libcore.rlib Env: OUT_DIR=/workspace/rust-hello-nes/output/build_main-0_1_0 CARGO_MANIFEST_DIR=/workspace/rust-hello-nes/main CARGO_PKG_NAME=main CARGO_PKG_VERSION=0.1.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=1 CARGO_PKG_VERSION_PATCH=0 (100.0% 0r,0w,0b,2c/2t): 曰く、プログラムサイズが ROM 上の領域を 347 KB ほど超過してしまったとのこと。 手元の nes.cfg によれば、0x7FFA = 32762 バイト、つまり約 32 KB しか存在しません。 ゴールが遠ざかっていく雰囲気を感じました。あまりにもあんまりで笑ってしまいました。 ld65 (リンカ) を改造して不要なシンボルを落とせるようにする (失敗) なぜこんなにサイズが大きいのか、原因は明らかでした。core crate はこの時点で一つのオブジェクトファイルである libcore.rlib.o になっているのですが、ここには core にあるすべての実装が入っているからです。 そして ld65 にはリンク時最適化のようなものがないので、使いもしない関数を含めてすべてバンドルしようとしているようです。そうなると ROM には到底収まらないということですね。 しかし、最適化がないのであれば、最適化を作れば良いのではないでしょうか。 od65 によれば、圧倒的に大きいのは確かに CODE セグメントです。 となれば、スタートアップルーチンから exports の依存関係ツリーを作り、参照されていないものを削除すれば解決できそうな気もします。リンカの魔改造の始まりです。 $ od65 --dump-segments ./output/libcore.rlib.o Segments: Count: 6 Index: 0 Name: "CODE" Flags: 0 Size: 416728 Alignment: 1 Address size: 0x02 (absolute) Fragment count: 280296 Index: 1 Name: "RODATA" Flags: 0 Size: 12346 Alignment: 1 Address size: 0x02 (absolute) Fragment count: 8758 Index: 2 Name: "BSS" Flags: 0 Size: 51 Alignment: 1 Address size: 0x02 (absolute) Fragment count: 51 Index: 3 Name: "DATA" Flags: 0 Size: 3308 Alignment: 1 Address size: 0x02 (absolute) Fragment count: 2104 Index: 4 Name: "ZEROPAGE" Flags: 0 Size: 0 Alignment: 1 Address size: 0x01 (zeropage) Fragment count: 0 Index: 5 Name: "NULL" Flags: 0 Size: 0 Alignment: 1 Address size: 0x02 (absolute) Fragment count: 0 今まで特にアセンブリを直接触って何かをしたことはありません。 最初は削除条件を厳しくしすぎてしまい何もしない ROM ができあがってしまいました。 しかし、だからといってもう少し保守的にやると、結局 ROM サイズが 150KB 程度にしか小さくできませんでした。これでは結局オーバーしてしまうことに変わりありません。 デバッグ出力を見る限りまだまだ不要なシンボルを詰め込んでいそうなので、多分最初のスタートアップルーチンとしてマークしている範囲が大きすぎるとか、何か間違ってるんだと思います。 と、いろいろ試行錯誤していたのですが、次第に export 境界の判別という問題がかなり難しいことに気づき始めました。 C や Rust 由来の普通の関数はまだよいのです。 というのも、コンパイラがきちんと .proc – .endproc というもので関数を囲んで生成してくれるからです。そうしておけばアセンブラが .o ファイルにそのまとまりのサイズを一緒に書き込んでくれます。 そのため、特定の関数が別の何を参照しているのかは、そのサイズの範囲内でどこに jmp しているのかを調べればよく、削除を決めたときもどこから何バイト削除すればいいのか比較的容易でした。 一方、直接アセンブリで書かれている関数 (ラベル) たちは自由奔放です。 処理のど真ん中にラベルがついていて外から横入りするようなこともあるみたいですし、極めつけは自己書き換えコードなる存在です。 最初に jmp $0000 という命令を見たときは首をかしげました。しかし、どうも本当に 0 番地に入っているアドレスに飛びたいわけではないらしいのです。その命令に到達する前に、ちょうどそのオペランドにあたるコード領域のメモリを上書きして使うらしいです。 つまり、 jmp 命令に到達する前に store 系の命令をつかい、 $0000 というオペランドそれ自体を書き換えてしまうということですね。すると CPU が jmp 命令に到達したときには、さも最初から jmp $1234 と書かれていたかのように書き換わっているとのことです。なにそれ怖い。 こうなるとどこからどこまでが一つの「関数」なのか判断するには、究極的に実行をシミュレーションする必要がありそうです。分岐などもあるでしょうからとんでもないことになるでしょうし、そもそもどういうステートでその処理に侵入するかによって莫大なパターンがあります。仮にそれを乗り越えてなんとか範囲が分かったとしても、それを適当な位置にちゃんとリロケーションできるのかも怪しくなってきました。 結局、時間切れもあって、このアプローチは断念することになりました。 既存のリンカの最適化はどうなってるんでしょうか。本当にすごいですね。 諦めて必要な部分だけ core を作る リンク時最適化が無理なのであれば、発想を転換するしかありません。 つまり私が最適化をします。必要な実装だけを含む最小限の libcore を書いてリンクすれば最低限動かすことはできるはずです。 言語機能に必要な marker trait ( Sized , Copy たち) などを含めると必要な実装は思ったより多いのですが、例えば四則演算は u8 だけに定義するなどの涙ぐましい努力によって、とにかく最小構成を目指しました。 そして再度コンパイルしてみると… $ make ... 中略 ... Completed welcome v0.1.0 [bin welcome] (100.0% 0r,0w,0b,3c/3t): やっと、コンパイルが通りました。長かったあ… ファイルが小さくなったので cc65 は無改造でいけるようになるという副次的効果もあります。 遠回りをしましたが、それにしても core crate そのものを書くなんていう経験はなかなかできないので、結構楽しかったです。 Rust 使いなら、プリミティブ型に impl [T] {} とかしてみたいと一度くらいは思ったことがあると思うのですが、それがまさに叶う瞬間でした。 できたもの 最後にもうちょっとライブラリを整理して見た目を整えて、こんな感じのソースコードが実行できるようになりました。 #![feature(no_core)] #![no_core] #![no_main] #[macro_use] extern crate cc65; use cc65::{cprintf, get_screen_size, goto_xy}; fn print_at_center<const N: usize>(line: u8, s: &[u8; N]) { let (width, _) = get_screen_size(); let padding = (width - N as u8) / 2; goto_xy(padding, line); cprintf!(b"%s\0", s); } #[start] fn start(_argc: isize, _argv: *const *const u8) -> isize { print_at_center(5, b"HELLO NES FROM RUST!\0"); print_at_center(15, b"ADVENT CALENDAR 2025\0"); print_at_center(20, b"STATIOLAKE\0"); loop {} } これだけ頑張った割に、C を不便にラップしただけで、Rust っぽいことはほとんどできないのは悲しいようにも思えますが、実際は、(自力では) Rust だけを書けばファミコンを動かせるようにできた、という喜びが大きいです。 ちなみに fizzbuzz も動きます。ちょっとは Rust っぽさあるかな…。 #![feature(no_core)] #![no_core] #![no_main] #[macro_use] extern crate cc65; use cc65::{cprintf, get_screen_size, goto_xy}; fn fizz_buzz(n: u8) { let mut i = 1; while i <= n { goto_xy(0, i - 1); match (i % 3, i % 5) { (0, 0) => cprintf!(b"FizzBuzz\0"), (0, _) => cprintf!(b"Fizz\0"), (_, 0) => cprintf!(b"Buzz\0"), _ => cprintf!(b"%d\0", i), } i += 1; } } #[start] fn start(_argc: isize, _argv: *const *const u8) -> isize { let (_, height) = get_screen_size(); fizz_buzz(height); loop {} } なんで for i in 1..=n じゃないのか、ですか?core に Iterator を実装しなかったからです…。 cprintf! マクロもフォーマット指定が自前なのは片手落ちですが、 format_args! をサポートするのはコード長的に相当大変そうだったので見送りました。 とはいえその辺も、頑張れば必要に応じて実装することも可能だと思います。 長かったですが、ここまでなんとかたどり着けました。 お付き合いいただきありがとうございました。 おわりに 相当難しい遊びでしたが、自分が持つ技術セットで考えれば一番楽しいルートを選べたとも思います。最初はずるいな〜と自分でも思っていたのですが、十分に学びのあるルートでした。 目論見通り、C 言語を中間言語として挟んだことで、何が起きているかがわかりやすく、自分であがける範囲が大きかったのも良かったです。 この方針で大きなものを作るのは難しいでしょうが、もうちょっとくらいは作り込めそうではあります。明らかにオーバーヘッドは大きいのでヌルヌル動くボリューミーなゲームは作れないと思いますが、リアルタイム性が低めな、それこそ迷路みたいなものならできても良さそうだなと。いずれ挑戦するかもしれません。 また今回、core crate のサブセットを再実装することで Rust で当たり前にできていることがどのような仕組みで解決されているのかの一端を体感しました。たとえば &str -> *const u8 のようなデリファレンスすらできません。 Unsize とか CoerceUnsize とかいう、普段なら目にもしないようなトレイトが必要なんだそうです。両手両足をもがれたようなプログラミングでしたが、それはそれで新鮮で面白かったです。 40 年以上前のハードウェアと現代の言語を無理やり繋げるという、誰得なチャレンジでしたが、ここまでお読みいただきありがとうございました! 明日の記事は、Rust Advent Calendar はまだ未定のようですが、ニフティグループ Advent Calendar は @su6y さんの「AWS IAM Identity Center経由でKiroを使ってみる」です!お楽しみに。 ※「ファミコン」「ファミリーコンピュータ」は任天堂株式会社の登録商標です。 ※本記事の内容は個人の技術検証に基づくものであり、任天堂株式会社とは一切関係ありません。
この記事は、 ニフティグループ Advent Calendar 2025  3日目の記事です。 はじめに こんにちは!新卒1年目のパクパクです OJT中のタスクの中でGraphQLで処理していたIssue作成のプロセスを、GitHub CLI(ghコマンド)に処理する作業を行いました。 この過程で学んだghコマンドについてご紹介します。それでは Let’s go!   目標 ghコマンドを使い、メインIssueとサブIssueを作成してプロジェクトに追加する   1. プロジェクトデータの取得 (Get Project and Field IDs) Issueを作成してプロジェクトボードで管理するには、まず必要となる各種IDを収集する必要があります。 ghコマンド で情報を取得し、 jq を使ってJSONデータを使います。   gh project view gh project view [<number>] [flags] プロジェクトの詳細情報を取得します。 オレンジ色の情報をコマンドで取得します オプション [flags] --owner : 個人またはOrganizationのアカウント --format : 出力フォーマット   例えば、Organizationが my-org である 1 番プロジェクトに関する詳細情報を取得したい場合は、以下のように入力します。 入力 $ gh project view 1 --owner my-org --format json 出力 { "closed": false, "fields": { "totalCount": 10 }, "id": "ABC_dkBO...", "items": { "totalCount": 50 }, "number": 1, "owner": { "login": "my-org", "type": "Organization" }, "public": false, "readme": "プロジェクト Readme...", "shortDescription": "プロジェクト 説明...", "title": "GitHub CLIでIssueを作成しよう", "url": "https://github.com/orgs/my-org/projects/1" } 末尾の -q .id オプションで、プロジェクトIDの値だけ抽出しました。 PROJECT_ID=$(gh project view 1 --owner my-org --format json -q .id)   gh project field-list gh project field-list [<number>] [flags] プロジェクトのフィールド情報を一覧表示します。 オプション [flags] --owner : 個人またはOrganizationのアカウント --format : 出力フォーマット   入力 gh project field-list 1 --owner my-org --format json 出力 { "fields": [ (...) { "id": "PVT_kw...", "name": "Status" , "options": [ { "id": "98234798...", "name": "In progress" } (...) ], "type": "ProjectType..." }, { "id": "abc123", "name": "Sprint" , "type": "ProjectV2Field" }, { "id": "def456", "name": "Point" , "type": "ProjectV2Field" }, { "id": "ghi789", "name": "Priority" , "type": "ProjectV2Field" }, (...) ], "totalCount": 5 } Status フィールドの ID を取得するために、下記のコマンドを使いました。 gh コマンドの結果を jq に直接渡して ID を抽出します。 STATUS_FIELD_ID=$(gh project field-list 1 --owner my-org --format json | jq -r '.fields[] | select(.name=="Status") | .id')     gh project item-list gh project item-list [<number>] [flags] プロジェクトに追加されているアイテム(IssueやPRなど)を一覧表示します。 オプション [flags] --owner : 個人またはOrganizationのアカウント --format : 出力フォーマット 入力 gh project item-list 1 --owner my-org --format json 出力 { "items": [ { "assignees": [ "pakupaku" ], "content": { "body": "# 概要nサービスローンチに向けて...", "number": 1, "repository": "my-org/backend-api", "title": "ユーザー認証機能の実装", "type": "Issue", "url": "https://github.com/my-org/backend-api/issues/1" }, "due": "2025-12-15", "id": "PVID_abc123", "labels": [ "bug", "high-priority" ], "linked pull requests": [ "https://github.com/my-org/backend-api/pull/2", "https://github.com/my-org/backend-api/pull/3" ], "point": 1, "repository": "my-org/backend-api", "sprint": { "duration": 14, "iterationId": "abc12345", "startDate": "2025-11-18" , "title": "Sprint" }, "status": "In Progress", "title": "ユーザー認証機能の実装" }, (...) ], "totalCount": 3 } プロジェクトアイテムの中から現在のスプリント情報を特定するために、各sprintのstartDateを取得します。   2. Issueの作成 (メインIssueとサブIssue) gh issue create gh issue create [flags] 新しいIssueを作成します。   オプション [flags] R , -repo : Issueを作成するリポジトリを選択します。 t , -title : Issueのタイトルを指定します。 b , -body : Issueのボディ(内容)を指定します。 l , -label : Issueのラベルを指定します。   このコマンドで、GitHub上でIssueが作成されます。 入力 gh issue create --repo "my-org/my-repository" --title "ログイン画面のUI実装" --body "Figmaのデザイン案に従って..." --label "feature"     gh issue view gh issue view {<number> | <url>} [flags] Issueの詳細情報を表示します 入力 gh issue view "https://github.com/my-org/my-repository/issues/2" 出力 title: ログイン画面のUI実装 state: OPEN author: pakupaku labels: feature comments: 2 assignees: developer123, reviewer456 projects: Development Board (In Progress) milestone: v1.0.0 number: 2 url: https://github.com/my-org/my-repository/issues/2 -- Figmaのデザイン案に従って、ログインフォームを実装します。 メールアドレス、パスワードの入力フィールドおよびバリデーション(Validation)を含めてください。   ここでも -q .id を使って、作成されたIssueのIDだけ取得できます。 入力 gh issue view "https://github.com/my-org/my-repository/issues/2" --json id -q .id   3. Issueをプロジェクトに追加する gh project item-add gh project item-add [<number>] [flags] プロジェクトにアイテム(IssueやPR)を追加します。 オプション ([flags] -owner : 個人またはOrganizationのアカウント -url : プロジェクトに追加したいIssueやPRのURL 入力 gh project item-add 1 --owner my-org --url "https://github.com/my-org/my-repository/issues/2"     gh project item-edit gh project item-edit [flags] プロジェクト内のアイテム(IssueやPRなど)のフィールド値を変更します。   オプション [flags] -id : 編集したいアイテムのID -project-id : 対象のプロジェクトID -field-id : 値を設定したいフィールドのID -single-select-option-id : 単一選択フィールド(Single Select)で設定したいオプションのID -iteration-id : イテレーション(Iteration)フィールドで設定したい値のID -date : 日付フィールドに設定したい値(YYYY-MM-DD形式) -number : 数値フィールドに設定したい値   例えば、プロジェクトの日付を指定したりする場合に下記のコマンドを使います。 入力 gh project item-edit --id "PVTI_lA..." --project-id "PVT_kw..." --field-id "PVTF_lAD..." --date "2025-12-8"       4. メインIssueとサブIssueを紐付ける gh api gh api <endpoint> [flags] GitHub APIに対してHTTPリクエストを送信します。   Issueをメイン サブ関係で紐付ける機能は、 gh コマンドではまだサポートされていません。そのため、 gh api コマンドを使ってGitHub APIを直接呼び出すことで対応します。 Request Bodyとして送信するデータはJSON形で渡します。 入力 # サブIssueのIDを指定 SUB_ISSUE_ID="I_kwDO..." # Request BodyをJSON形式で作成 JSON_BODY=$(printf '{"sub_issue_id": "%s"}' "$SUB_ISSUE_ID") echo "$JSON_BODY" | gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" "/repos/${OWNER}/${REPO}/issues/${MAIN_ISSUE_NUMBER}/sub_issues" --input -   このようにして、GitHub REST APIのエンドポイント( .../sub_issues )に対して直接POSTリクエストを送信し、Issueの親子関係を設定しました。 まとめ これまではブラウザ上で操作するのが当たり前だと思っていましたが、今回、GitHub CLI( gh コマンド)を使ってみて、Issue作成から親子関係の紐付けまでできるということを学びました。 UIだけでなく、CLI環境でも色んな作業ができることを知り、これからもCLIツールを活用して、開発効率を上げていきたいと思います! 明日は、中井さんの「ファミコンのソフトを作る。Rust で」です。 お楽しみです   参照 https://cli.github.com/
この記事は、 ニフティグループ Advent Calendar 2025 2日目の記事です。 こんにちは。ニフティポイントクラブ開発・運用担当の西根です。 この度、AWS認定資格の一つである SysOps Administrator – Associate (SOA-C02) に合格しました。 AWS Certified SysOps Administrator – Associate (SOA-C02)は2025年9月30日よりAWS Certified CloudOps Engineer – Associate (SOA-C03)に更新されています。 実は、上期の目標に設定していたにもかかわらず、9月に入るまで全く手をつけていないという状況でした…。 そこから 約3週間(実働学習20時間) という短期間で、なんとか合格までたどり着いた経緯と勉強法をご紹介します。 SAAは持っているけれどSOAはどうしようか迷っている方や、とにかく時間がない!という方の参考になれば幸いです。 筆者の前提スキルと状況 まずは、学習開始前の私の状況です。 保有資格: 1年前にSAA(ソリューションアーキテクト アソシエイト)に合格済み。 AWS実務経験: 業務でAWSは使用していますが、AWS Organizationsを使ったアカウント管理などは別部署が担当しており、知識・経験ともにほぼゼロの状態でした。 状況: 上期の目標達成のため、「とにかく最速で」 合格する必要がありました。 学習戦略 学習戦略は「とにかく問題演習から入る」にしました。 というのも、学習期間は 3週間(合計1200分 / 20時間) しかなく、動画教材を最初から全部見るような余裕はなく、以下の戦略を取る必要がありました。 まず問題演習(Udemy)を解く。 間違えた問題、理解が曖昧な問題の解説をしっかり読む。 どうしても概念すらイメージできないサービスだけ、ピンポイントで動画教材を視聴する。 AI(ChatGPTなど)を壁打ち相手として使い、知識の穴を埋める。 時間の作り方 確保した時間は以下の通りです。 平日: お昼休み: 40分(ご飯を食べながらUdemy動画を流し見 + 20〜30分の問題演習) 通退勤: 0〜30分(気が向いたらやる程度) 休日: 予定がない日に 2〜4時間 集中して確保 使用した教材 使用したのは以下の3つです。 [動画教材] AWS認定CloudOps Engineer Associate(SOA-C03)試験 対策トレーニング 主に知識補完用。全編は見ず、Systems Manager, Organizations, Service Catalog, Control Towerなど、全く知らないサービスの章だけを1.25倍速で視聴しました。 [問題演習:メイン] AWSトップ講師によるAWS認定SysOpsアドミニストレーター アソシエイト模擬試験問題集(5回分325問) 今回の学習の核です。 これをひたすら周回しました。 正答率を回数ごとに記録してもらえるので、成長が可視化されてモチベーションになりました。 [問題演習:直前] AWS認定資格 WEB問題集&徹底解説 Udemyの問題に慣れすぎたため、受験前日〜当日にかけて「無料問題」のセクションを解き、知識の最終確認をしました。 AI活用が合格の鍵 今回の短期合格の要因として、 AIの活用 が非常に大きかったと感じています。 SAAと違い、SOAはSystems Manager (SSM) やOrganizationsなど、「実際に組織で使っていないとイメージが湧きにくい」サービスが頻出します。 これらをドキュメントだけで理解しようとすると時間がかかりますが、AIに壁打ち相手になってもらうことで、効率的に理解を深めることができました。 活用例1:サービスの比較と違いの明確化 例えば、SSMの「Run Command」と「Runbook (Automation)」の違いが曖昧でした。 そこで、AIに以下のように質問しました。 (質問) AWS SSMのRun CommandとRunbook(Automation)の違いを、初心者にもわかりやすく教えてください。 (AIの回答要約) Run Command: 目的: 複数のEC2やオンプレミスサーバーに対して「単発のコマンド(シェルスクリプトやPowerShell)」を実行する機能。 例: 「全サーバーにパッチを当てる」「ログファイルを収集する」 Runbook (Automation): 目的: もっと複雑な「一連の運用タスク」を自動化する機能。Run Commandの実行、Lambdaの実行、EC2の作成などを組み合わせたワークフローを作れる。 例: 「AMI(マシンイメージ)の作成とパッチ適用を自動化する」 このように、AIに「〇〇と××の違い」を平易な言葉で説明してもらうことで、公式ドキュメントを読むより早くイメージを掴むことができました。 もちろん、AIが常に真実を教えてくれるとは限らない(ハルシネーション)ため、 最終的なファクトチェックは必要 です。しかし、そもそも何から調べていいかわからない時の「とっかかり」として、非常に優秀でした。 活用例2:直前対策チートシートの作成 試験直前には、AIに「SOA-C03の試験に出る重要なサービスとキーポイントをまとめたチートシートを作って」と依頼しました。 作成されたリスト(SSM, CloudWatch, Organizations, Service Catalogなど)を眺めることで、頭の中を整理して試験に臨むことができました。 実務でSOAはどう活きているか? 正直なところ、1年前に取得したSAAではAWSのサービスをある程度網羅的に学習することとベストプラクティスをインプットすることが主目的であり、日々の業務で「あ、これSAAでやったやつだ!」と直接的に感じる場面はそれほど多くありませんでした。 しかし、SOAに関しては実務で活かせているなという手応えがあります。 ログ監視の提案ができるようになった 具体的な変化として、チーム内で「システムのログ監視方法を見直したい」という話題が上がった際のエピソードがあります。 これまでの自分なら方法を調べることから始めていたと思いますが、「CloudWatch Logsのメトリクスフィルターを使用すれば、特定のエラー文字列を検知して簡単にCloudWatch Alarmを発火させられますよ」 と、具体的な実装方法を含めた提案を調べずに行うことができました。 自社サービスの開発・運用・保守を一貫して行うチームにおいて、「どう運用していくか」「どう守るか」というSOAの知識は、開発者にとって非常に強力な武器になると感じました。 まとめ 今回の合格の勝因は、以下2点に尽きると思います。 良質な問題集(Udemy)を周回したこと 使用したUdemyの模擬試験は、実際の試験より少し難易度が高めに設定されている印象でした。これを解き切ることで、本番で慌てず対応できる実力がつきました。 AIを「壁打ち相手」として活用したこと 実務で触れないサービスの理解を、AIとの対話でスピーディに補完できました。 SAAに合格したものの、次のステップを迷っている方にはSOAの受験をおすすめです。 SAAが「設計」にフォーカスしているのに対し、SOAは「運用・監視・トラブルシューティング」に重点が置かれており、AWSをより深く理解するのに役立ちます。 時間がない方も、問題演習とAI活用を組み合わせれば、効率的に合格を目指せるはずです。 次回はもう少し時間に余裕を持って効率よく勉強したいと思います!  
はじめに ニフティ アドベントカレンダー トップバッターの西野です。エンジニアブログではほぼ毎回スクラムの記事を書いています。アドカレの枠をとりにいった11月は「12/1、間に合いそう!」と思っているのに当日になって書いています。あわてんぼうのサンタクロースの前倒し精神を見習いたいです。 この記事では、AIを活用し「質の高いレトロスペクティブ」の準備を30分以内に終わらせるコツ、レトロスペクティブ中のアイデア発散と収束にどうAIを役立てるかという内容を、実際に自分たちのチームで活用している具体的なプロンプト付きで紹介しています。ぜひ拡散してください。 スクラムでどうAI活用するか 開発者にもプロダクトオーナーにもAIのビッグウェーブが来て早数年。 スクラムマスターとしてAIが使える領域がないかいくつか試してみたのですが、 ファシリテーション:特にアイデアの収束 チーム分析:特に会話ログに基づく感情・行動分析 この2点についてAI活用が効果的だと思うので、AI活用が向いている領域と具体的な使い方を紹介します。 スクラムでAI活用ができる領域 AI活用により実行時間が短縮できること アクションの作成 ブレスト内容からPBIの受け入れ基準を作成する ミーティングの最後に実行可能なアクションアイテムを生成する 課題の発見 ミーティングの会話内容、ベロシティといったデータに基づくチーム課題の発見 自分が知らないやり方の選択 レトロの手法、ミーティングの手法など AIじゃないと難しいこと 会話における客観的な感情分析 分析結果が正しいかどうかは別なので判断は人間がする 膨大な分析 1スプリント〜半年間の、トランスクリプト(Google Meetなどの文字起こしによる会話ログ)を分析 トランスクリプトの会話内容とベロシティの関係性 一番効果的だった使い方:レトロスペクティブ チームでやってみて一番効果的だったスクラムにおけるAI活用は、レトロスペクティブでした。 自分はスクラムマスターとしてレトロスペクティブの手法を学んで実施していますが、そのぶんレトロの準備やファシリテートが属人化しやすく、他のメンバーでファシリを回す場合でもサポートとして入るケースが多い状態でした。 しかし、AIを活用することでレトロスペクティブの質を維持してファシリをローテさせることが可能となり、レトロスペクティブの内容にもなりますが準備時間も おおむね30分程度 と大きく短縮できています。 データの仕込み方 Google CalendarのMeetを想定した方法となります。Zoomなどほかミーティングツールでも大きく方針は変わらないと思いますが、オンラインを介さずリアルの場でミーティングをする場合は文字起こしを忘れないようにする必要があります。 ここではGoogle MeetやGeminiを軸とした使い方を紹介しますが、ほかのツールでもおおまかな流れは変わりません。 可能な限りスクラムイベント(ミーティング)をGoogle Meetで開催する Google CalendarのMeet設定で、「会議を文字起こし」をデフォルトONにしておく。繰り返し予定に対して反映するとGOOD。 レトロスペクティブのテーマ Google Driveの「Meet Recordings」の「Geminiに相談」にプロンプトを投げる レトロスペクティブのテーマを決めるためのプロンプト例 シンプルなテーマ提案 過去1週間(※スプリントの長さに合わせる)の会話を分析して、レトロスペクティブのテーマとして最適なものを5つ提案してください 長所と課題分析 過去1週間の会話を分析して、チームの長所と課題を指摘してください 出来事を振り返る 過去1週間の会話を分析して、主要な出来事を挙げてください。具体的には、成功した点(Keep)、課題となった点(Stop/Improve)、そして議論の中で繰り返し現れた重要なキーワードやトピックを含めてください 頻発する課題の特定 過去1週間の会話を分析して、同じ問題が繰り返し議論されていた箇所を特定してください。 議論傾向の特定 過去1週間の会話を分析して、「プロセス・ツール」と「人間関係・コミュニケーション」の2つに分類し、どちらの課題の議論に最も時間が割かれていたか、その比率を示してください。そこから、より深い議論が必要な課題を5つ提案してください 感情分析 過去1週間の会話を分析して、チームの感情分析をしてください。そこから見つかったレトロスペクティブのテーマとして最適なものを5つ提案してください トランスクリプト(会話ログ)だけだと的外れな分析を返してくることも多いため、しっくりくるテーマになるかはファシリテーターが事前にトライアンドエラーしておきます。 AIを使ったレトロスペクティブの準備ではここが一番大変です。 レトロスペクティブの手法を決める チームの課題が絞り込めたら、その課題を解決するための方法を尋ねます。 レトロスペクティブに関する情報はそこまで多くないのか、目新しい振り返り手法の提案は基本的に出てこないように思います。 一方で、チームメンバーが「トラブルの振り返りで、変わったレトロスペクティブのやり方を提案してほしい」とAIに頼んで「過去の自分に宛てて手紙を書くなら、いつ、どんな内容にするか」という今までのレトロで採用したことがないアイデアが出てきて、新鮮なレトロスペクティブを開催することもできました。マンネリ化したテーマの場合は振り返り手法をゼロからAIに考えさせてみるのもいいかもしれません。 レトロスペクティブの手法を決めるための プロンプト例 シンプルな振り返り手法の提案 「複雑なタスクの見通しと計画」についてレトロスペクティブを行いたいと思います。どんなレトロスペクティブの手法を提案し、その理由を説明してください 感情にフォーカスした振り返り手法の提案 チームの心理的安全性を高めるのに役立つレトロスペクティブの手法(例:Mad Sad Glad、Sailboatなど)を提案し、その理由を説明してください 真因をさぐるための振り返り手法の提案 「障害がなぜ再発するか」については、根本原因の特定が必要であることを示唆します。根本原因の深掘りに適したレトロスペクティブの手法(例:5つのWhy、フィッシュボーン図など)を提案し、その理由を説明してください 新鮮な振り返り手法の提案 従来のレトロスペクティブの手法にとらわれない、ユニークで感情的な要素を含むレトロスペクティブの手法を3つ提案してください レトロスペクティブを組み立てる ここまでで、チームの課題とその課題の検討方法が決まりました。あとは時間配分を決めます。 AIの活用はレトロの準備だけでなく、アクションアイテムの絞り込みにも使うので、以下のようなプロンプトがおすすめです。 レトロスペクティブの組み立てをする プロンプト例 AIを活用したレトロスペクティブの時間配分とコツ 「障害がなぜ再発するか」というテーマで、5つのWhyを用いてレトロスペクティブを行います。時間配分をふくめて、1時間のスクラムイベントの組み立てをしてください。最初にアイスブレイクを入れてください。アクションプランの絞り込みは、出た意見に基づいてGeminiで行います。このレトロスペクティブのファシリテーションをするときのコツも添えてください。 レトロスペクティブを実施する あとは、決めた時間に沿って進行し、現状把握やアイデア出しを行います。 アイデアを出すフェーズは、おおまかに発散フェーズ(たくさんアイデアを出すフェーズ)と収束フェーズ(アイデアからアクションを絞り込むフェーズ)に分かれます。 AIを活用したアイデアの発散と収束 AIはあくまでミーティング中の会話しか知らないため、発散フェーズは「ミーティング以外の場で起きたことを知っている人」=スクラムチーム本人に任せることをお勧めします。 収束フェーズはAIが得意とするところです。出たアイデアから意見をまとめたり、絞り込ませてスクラムチームがピンとくるアクションを出せるかを高速に試すことができます。 レトロスペクティブ中に出たアイデアの収束をする プロンプト例 (ホワイトボードのキャプチャや、アイデアリストなどのテキストデータをAIに伝えたうえで)出た意見をもとに、1週間(※スプリントの長さに合わせる)実行可能なアクションアイテムを5つ挙げてください 改善アクションの決定 このプロンプトで出たいくつかのアクションアイテムを選ぶ方法は、話し合いでもいいですし、良いアイデアが多くて意見が割れるようであればドット投票などの投票でもかまいません。 次のスプリントで実施するアクションアイテムを選んでAIを使ったレトロスペクティブの完了です。 最後に レトロスペクティブで大切なことは「チームが主体となって」スプリントを振り返ることです。より大量かつ詳細にチームのデータが取れるようになったときには、AIを活用するなかで意見を出すフェーズはAIに行わせて、収束するフェーズをあえて人間がやるという方向性もあると思います。 肝心なのは「レトロスペクティブの全てをAIに任せきりにしない」ことです。 今の時点のAIでは、チームに関する情報の全てを拾いきることはできません。たとえばAIは朝のチーム内の雑談も、隣の席同士で会話のなかで相談した設計の話も、机の散らかり具合も、チームの中に漂う空気感というのも正確にはわかりません。 スクラムチームについて一番詳しいのがスクラムチーム自身なのは、当面は変わらないと思います。 ここまでAIを活用する話を書いていますが、この記事を書くことそのものにはほとんどAIは使っていません。(プロンプトのアイデアや校正にはAIを活用しています) これは、ブログ記事でアウトプットすることで自分の考えを整理することを目的としているからです。スクラムマスターは、要所要所でAIを使うことがチームが目指す目的に沿っているのかも確認する目線があるといいと思います。 次回(自分の掲載が1日遅れなので今日ですが……)のアドベントカレンダーは西根さんによる「SAA持ちエンジニアがAI活用と問題演習でAWS SysOps (SOA-C03) に3週間で合格した勉強法」です。お楽しみに!
こんにちは!NIFTY engineeringブログ運用チームです! 今年もあっという間に残りわずかとなりました。クリスマスが迫り、アドベントカレンダーの季節が到来しましたね! ニフティグループでは毎年、アドベントカレンダーに積極的に参加しており、今年でなんと10回目の開催となります! 日頃の知見をアウトプットする機会として、ニフティグループのエンジニアが楽しみながら成長していくことができています。 今年も皆様に新たな技術や知識をお届けできることを楽しみにしています! アドベントカレンダーとは? 元々はクリスマスまでの日数をカウントダウンするために使われていたカレンダーで、12月1日からはじまり、25個ある「窓」を毎日1つずつ開けて中に入っている小さなお菓子やプレゼントを楽しむものです。 このカレンダーにならい、定められたテーマに従い参加者が持ち回りで自身のブログやサイトに記事を投稿する、リレー形式のブログ執筆イベントです! ニフティグループ アドベントカレンダー ニフティグループではフリーテーマとなっておりますので、好きに執筆してもらっています。 また、記事に関してはQiita様のアドベントカレンダーページにて登録させていただき、 公開自体は本ブログ(NIFTY engineering)や ニフティライフスタイル Tech Blog 、Qiitaにしていく予定です!(ニフティ、ニフティライフスタイル、セシールでそれぞれ投稿場所が異なります) ニフティグループ AdventCalendar 2025 アドベントカレンダーでは、ニフティグループのエンジニアが日頃の業務で培ったノウハウを共有していきますのでぜひチェックしてみてください!
この記事は、リレーブログ企画「Maker Faire Tokyo 2025ボードゲーム制作リレーブログ」の記事です。 こんにちは!Maker Faire Tokyo 2025 リレーブログ、前回のムサシさんからバトンを受け取りました、西根です。 前回までは、私たちが作ったオリジナルカードゲームのルールやデザインがどうやって完成したかをご紹介しました。 しかし、その時点ではルールもデザインも、まだすべてPCの中のデータに過ぎません。 この記事では、そのアイデアが、どうやって皆さんの手元で遊べる「モノ」になり、イベント当日を迎えたのか。その泥臭くも楽しかった「製造・出展プロセス」の物語を振り返ります。 初めての「仮入稿」と「仮印刷」 アイデアを初めて「紙」にする日。 デザイン担当の西野さんとイラスト担当のムサシさんが作ってくれた入稿データで「仮印刷」を試しました。 数日後、印刷所から届いた仮印刷のカードを初めて手にした時は、本当に自分たちが考えたものがボードゲームになるんだ…!と嬉しくなりました。 データ上で完璧に見えても、紙にした瞬間に「色が沈む」「文字が小さすぎる」といった問題が発覚するのが「印刷あるある」だと聞いていたのですが……今回はそれがほぼありませんでした。 むしろ「PP加工(ツルツルにする加工)なしでも、思ったより光沢があるかも?」といったポジティブなギャップがあったくらいです。 これは間違いなく、入稿データ作成に強いメンバーがいてくれたおかげだと、この時強く思いました。 これは本印刷後のカードですが、発色や光沢感もとても良い感じです!   カラフルな裏面も綺麗に印刷していただきました!   予期せぬミッションとクオリティの追求 「モノ」としてのクオリティをどこまで求めるか。これは予算とスケジュールの戦いです。 突然の追加ミッション:「急遽、パネル置けます!」 イベントが近づいてきたある日、「ブースにパネルを置けることになりました!」と連絡が。 嬉しいチャンスであると同時に、印刷所に入稿するとなるとデザイン担当の西野さんに追加のタスクをお願いしなければいけませんでした。 期限が迫っていたため、すぐに西野さんに「いつまでに何を決めて依頼すれば間に合うか」を相談し、パネルに載せる内容と構成を急いで決めました。 この時デザインしてもらったパネルの内容が、後述するルールブックの表面デザインにも活用できたのは、結果的にとても良かったです。 ルールブックも「本物」にしたい ルールブックは、当初は社内のプリンターで印刷する想定でした。 しかし、「せっかくカードを綺麗に作るなら、ルールブックもちゃんとしたものにしたい!」という思いが捨てきれず、なんとか予算を工面できないか調整を重ねました。 その結果、イベント直前の9月末頃、急遽「印刷会社で印刷できる」ことが決まりました! 喜びと同時に、社内の発注プロセスを進めなければなりません。社内調整の知見が全くなかった私は、いっけいさんに泣きつき、発注から納品までをめちゃくちゃサポートしてもらいました。本当にありがとう、いっけいさん…。 写真だと伝わりづらいですが、ツヤっとした光沢紙に印刷したことで「本物」感が増しました! イベント前日に西野さんとムサシさんにルールブックを綺麗に折ってもらい、当日の朝なんとか梱包を終えました。 スタッフ体験会 ゲームが物理的に完成し、イベント当日が近づいてきた頃、当日の運営を手伝ってくれるスタッフの皆さんに向けて体験会を実施しました。 そこで直面したのは、 「このゲームのことを全く知らない人に、口頭でルールを説明する難しさ」 です。 テストプレイに参加していた人も、普段からボードゲームをしている人が多く、ルールを理解するということに慣れているということをすっかり見落としていました。 イベント当日はお客様に体験してもらう予定だったので、口頭で説明するにはルールを複雑にしすぎたか…?と不安になりましたが、体験会が終わった後に「面白い」「カードがかわいい」といった感想をもらえたのは、本当に嬉しかったです。 同時に、こんな貴重なフィードバックももらいました。 「特殊カード、小さいお子さんにはちょっと複雑かもね…」 …確かに! Maker Faireは親子連れも多いイベントです。このままでは楽しんでもらえない層が出てきてしまう。 私たちは急遽、当日スタッフの皆さんにお願いし、小さいお子様には「特殊カードをすべて『10』として扱う」という簡略化ルールで遊んでもらうことにしました。 これにより、ほぼ通常のブラックジャックと同じルールで遊べるようになり、当日は本当に色々な年代の方に楽しんでいただけたと思います。 体験会で率直な意見をもらうこと、そしてそれに応えてくれる当日スタッフの皆さんの柔軟な対応力に、心から感謝しています。 決戦のMaker Faire当日 そして迎えた当日。 自分たちが作ったゲームを、ブースに来てくれた人たちが手に取り、遊んでくれている。 その光景を見ているのは、なんとも言えない緊張と喜びが入り混じった時間でした。 アンケートでは「ルールが面白かった!」「子供が楽しんでいた」といった声をいただき、改めて「ものづくりって楽しいな」というシンプルな気持ちを思い出させてもらいました。 普段私が作っているものはソフトウェアですが、実際に手で触れる「モノ」があるものづくりも、やってみれば意外となんとかなる。そして、 自分が作ったもので誰かが喜んでくれる瞬間の嬉しさ は、ソフトウェアもボードゲームも変わらないんだな、と感じました。 アイデアを「形」にして学んだこと 振り返ってみて、学んだことは大きく2つあります。 当たり前ですが、ボードゲームを1から作るのは本当に大変でした。 決めることも、調整することも多い。でも、それ以上に、実際に遊んでいるところを見た時の嬉しさは格別でした。本当にやってよかったです。 色んな人を巻き込むと、思ったよりも快く協力してくれる。 ただし、丸投げはダメです。できるだけ「自分はこうしたい」という意見を持って質問したり、疑問点を言語化したりして相談に行くことで、お互いが幸せになれると実感しました。 有志で関わってくれた開発メンバー、デザイナーの皆さん、印刷所の方々、そして当日ブースに遊びに来てくれた全ての皆様に、心から感謝を伝えたいです。 本当にありがとうございました!
普段、何気なく使っているインターネットやWEBサービス。その要となるのが、通信端末や各種サーバーの間をつなぎ、情報の伝送を行うネットワークです。ニフティにも専門のネットワークチームがあり、データセンターやニフティ従業員が働くオフィスのネットワーク設計・構築・運用などを担っています。 「つながるのが当たり前」というプレッシャーのなかで、日々の業務にあたるネットワークチーム。 前編 では仕事のやりがいや、苦労などについてメンバーに語ってもらいました。後編ではニフティという会社の良いところ、チームに迎えたいメンバー像、さらには各々が描く今後のキャリアについて聞きました。 キャリアや部署の垣根を超えて交流できる機会が多い みなさんが思う「ニフティの良いところ」を教えてください。 Sさん ニフティの良さはなんといっても、社員同士のコミュニケーションが活発なことだと思います。懇親会など交流の場も多いですし、社内コミュニケーションツールも積極的に活用されています。それもあって年齢やキャリア、部署の違いに関係なく仲の良さ、距離の近さを感じますね。 他部署の人と気軽につながれるのはいいですね。普段の業務では触れる機会のない、さまざまな知見を得ることができそうです。 Sさん そうですね。知見をシェアする社内の勉強会なども定期的にあって、Slack内の勉強会を盛り上げるチャンネルがしっかり機能しています。誰かが投稿したメッセージに対するレスポンスも非常に多くて、みんながコミュニケーションを大事にしているというか、スルーしないのもニフティの特徴なのかなと思います。 それから、労働環境でいうと休日は多いですね。有給休暇も取りやすいですし、ワークライフバランスという点でも満足度の高い環境だと感じます。 Tさん 制度や待遇の面でいうと、フレックス勤務が認められていて勤務時間の自由度が高い点や、小学生以下の子供がいる場合は週3でリモートワークができる点、有給とは別に育児関連で取得できる休暇がある点など、かなり柔軟な働き方ができる制度が揃っています。 私自身はフレックス勤務をよく利用していますね。コアタイムが11時から14時までと定められていて、その時間さえ含めればいつ出社してもOKというルールです。前日の夜が遅かった時は翌朝の出社時間を11時にずらすなど、その時々の状況に合わせて調整することで、良いコンディションで働けていると思います。 制度以外の良さでいうと、何が浮かびますか? Tさん Sさんも話してくれましたが、やはり社員同士の仲の良さは感じますね。私は中途入社なのですが、Slack上に中途入社組が集まるチャンネルもあって、みんなでご飯を食べに行くきっかけになっています。あとは社内部活もたくさんあって、同じ趣味を共有できます。私が所属するサバゲー部でも、色んな部署の人たちと週末にサバゲーをしています。他にも、2か月に1度くらい、オフィス内のセミナールームで自由に集まりお酒を飲む交流の場もあったりして、つながる機会はかなり充実していると思います。Sさんは毎回のように参加していますよね。 Sさん そうですね。他部署の人たちと気軽に話せる機会で、思いがけない知見や発見を得られることも多いので。 Mさんはいかがでしょうか? ニフティの良さというと何が思い浮かびますか? Mさん 二人がほぼ言ってくれましたが、あえて被せると柔軟に働ける環境という点ですかね。フレックスや休みの取りやすさも、業務調整をやったうえではありますが、申請してNGが出たことは一度もありません。そこは基本的に融通が利く会社だと思います。 それ以外で個人的に良いと思うのは、さまざまな技術についてキャッチアップしやすい環境であること。技術に対する感度が高く、それを周囲にシェアしてくれる人が多いんです。たとえば、Slack上に色んな分野の最新情報を書いてくれる人がいるので、それを追っていくだけで自分が普段カバーしている領域以外についても知ることができます。とてもありがたいですし、自分も情報を得たら積極的にシェアしようという気持ちになりますね。 ネットワークの知識をベースに、色んな技術を吸収できる人が理想 チームに新しいメンバーを加えるとしたら、どんな人に来て欲しいですか? Mさんはリーダーの立場から、望む人物像や歓迎するスキルを教えてください。 Mさん ネットワーク関連の技術っていわゆる「枯れた」ものが多いイメージもあると思いますが、そのなかでも新しい技術はどんどん出てきていますし、自動化などによって運用面でも進化し続けています。そうした新しい技術に目を向けて、積極的に取り入れようとする好奇心を持った人が来てくれるといいなと思いますね。 性格的なところでいうと、この仕事はトラブル対応が一つの重要な役割になるので、イレギュラーな事象に対してパニックにならず、平静に構えていられること。心の中では動揺してもいいんですけど、そこで立ち止まらずに動き続けられる人がチームにいると非常に頼もしいです。 では、Tさん、Sさんはいかがでしょうか? Tさん 今のMさんの話と少し被りますが、ネットワークに関する最低限の知識を持ったうえで、自動化のような新しいことに取り組んでもらえる人が来てくれると嬉しいです。現時点でそうしたスキルを備えていなくても、新しいことに関心があり、常にキャッチアップしていく意欲を持った人であれば、ニフティは成長できる環境だと思うので。 Sさん もちろんネットワークに関する知見やスキルを持っている人はすぐに活躍できると思いますが、それ以外にも何か得意なことがあると、なお良いのかなと思います。僕らが普段業務で取り扱わないような技術に長けている人が来てくれると、メンバーの視野も広がりますし、新しい刺激を得られるのかなという気がしますね。 たとえば、今は全社的にクラウド環境への移行が進んでいるのですが、ネットワークチームには現時点でクラウドに特化した知識を持ったメンバーはいません。一人でもクラウドに明るい人がいてくれたら、ネットワークチームでも移行がスムーズに進むのかなと思います。自分でもそこを補うために、勉強を始めようと考えているところです。 ネットワークのスペシャリストとして、さらに技術を磨いていきたい みなさんの今後のキャリアの展望や、挑戦してみたいことを教えてください。 Tさん 先ほどSさんが、「ネットワークに関する知識がベースにありつつ、プラスαの強みがあると良い」と言っていましたが、それは私も同感で。私の場合、直近でAWSの案件に携わっていたこともあって、AWS周りにもっと強くなりたいと思っています。そうやって得意なことを増やして、ネットワークエンジニアとしての幅をどんどん広げていきたいですね。そのうえで、色んなことに挑戦でき、学ぶ機会も多いニフティの環境はかなりの後押しになると思います。 Sさん 私はネットワーク機器を触り始めて2年ほど経ちますが、まだまだ知らないことがたくさんあると思っています。機器に関しても設定に関してもさらに吸収していきたいですし、これまで会社で取り扱ってきた機器だけでなく、他のベンダーさんの機器も触ってみたいという思いがありますね。 キャリアに関しては正直、そこまで明確なものはまだありません。ただ、今の業務内容は自分に合っていると思うので、当面はそのレベルを上げていくことに集中したいです。 Mさん 私もキャリアというより、「やりたいこと」になってしまうのですが、機械って壊れることもありますし、トラブルはどうしても生じてしまうものです。大事なのはトラブルが起きた時に、ネットワーク側で自律的に立て直していける仕組みを作ること。そのためには、ネットワークの知識だけでなく、設計や構築といった開発のスキルも必要です。今後はそうした設計力を磨いて、強固なインフラを構築できるエンジニアになりたいと考えています。 そうしたスキルを学ぶ環境も、ニフティにはあるのでしょうか? Mさん そうですね。社内にも知見を持った人はいますし、社外のエンジニアのネットワークで公開している情報を拾ったり、勉強会に参加したりといったことも奨励されているので、学びやすい環境ではあると思います。毎週のチーム会でも、「こういう勉強会やイベントがあります」という情報は共有されますし、業務の調整さえできれば勤務時間の範囲で参加することも可能ですので。こうした環境をうまく利用して、ネットワークのスペシャリストとしての力を磨いていきたいと思っています。 前編もご覧ください! 今回はニフティのネットワークチームのインタビュー(後編)の様子をお届けしました。前編の記事はこちらをご覧ください。 【インタビュー】「つながるのが当たり前」。だからこそ普段はなるべく目立たない存在でありたい【ニフティ ネットワークチーム前編】 このインタビューに関する求人情報 /ブログ記事 ニフティ株式会社 求人情報
はじめに こんにちは!!新卒一年目のパクパク、やまだ25、大村です。 本記事では、私達が参加したエンジニア定例合宿で開発した、ユーザ投票ベースの電車混雑予想アプリを紹介します。 エンジニア定例合宿の詳細につきましては以下の記事をご覧ください。 今年はいつもと違う?ハッカソン合宿に行ってきました!@マホロバ・マインズ三浦   メンバー紹介 パクパク 普段の業務 : 入会会員の運用 今回の担当 : フロントエンド ひとこと : アニメで見た合宿の宴会が実在してて感動しました。 やまだ25 普段の業務 : データ基盤 今回の担当 : バックエンド ひとこと : 3日目にホテルの窓からうっすらと富士山が見えて感動しました。 大村 普段の業務 : 会員基盤の運用 今回の担当 : バックエンド、DB ひとこと: ホテルで食べた7食全部が豪華でした。   アプリ紹介 概要 チームWATCHME.mdでは、主観ベースの混雑予想アプリを作成しました。 実装したもの: ユーザがある路線の区間の混雑率を投稿 選択した路線の混雑度をヒートマップのように、区間ごとで色分け 実装しきれなかったもの: 曜日や天気、祝日などを考慮して、混雑度に重み付け ユーザごとの混雑度の感じ方に応じて、表示を調整 成果物 検索画面   結果画面 経路上の各駅間において、 どのくらい混んでいるのかを色合いで教えてくれます 検索結果 どの程度混んでいたかを共有   使用技術 フロントエンド: React バックエンド: Python(FastAPI)、PostgreSQL その他: Docker、Docker Compose 開発の流れ 事前準備 アイデアソン 使用技術調査 1日目: 仕様書作成 機能要件 API設計 DB設計 GitHub、Dockerでチーム開発の環境構築 2日目: 環境構築・実装 午前 FastAPI、Reactの環境構築 テーブル作成 午後 メイン・結果画面実装 API 中身実装 3日目: 最終調整・成果発表 午前 テスト バグ修正 午後 成果発表   工夫したこと 画面レイアウトについて メインの画面を混雑率の検索画面とし、ユーザは路線名、出発駅、到着駅を選択するだけで混雑率をすぐに検索するように画面レイアウトを設計しました。 投票画面の部分も同様に路線名と出発駅、到着駅、混雑率を選ぶだけで投票できるように設計し、ユーザの操作数を少なくするよう工夫しました。 タスク管理について 我々のチームではタスク管理としてGitHub Projectsのカンバンを使いました。これにより、各メンバーの作業状況や各タスクの進捗状況を一目で確認することができ、さらに手が空いたら別のタスクにすぐに取り掛かることができました。 また、開発以外のタスク(勤怠の申請や日報の作成など)もカンバンに記載することで申請漏れなどを防ぐことができました。   学んだこと・成長したこと Zustand 今回の合宿では、フロントエンドの状態管理ライブラリとしてReduxの代わりにZustandを初めて使用してみました。Reduxと比較すると、Zustandはシンプルでした。 Reduxでは actions や reducer など複数のファイルにわたってコードを記述する必要がありましたが、Zustandでは一つのファイル( appStore.ts )で路線、駅、混雑度データなどすべての状態を管理できました。 // Redux: actionTypes.ts + actions.ts + reducer.ts + コンポーネント dispatch(actions.setDepartureStation(station)); // Zustand: appStore.ts + コンポーネント setDepartureStation(station); また、メイン画面で駅を選択すると、結果ページで props を渡さずに駅データをすぐに使用できた点も楽でした。 Zustandを使用することで、コード量を削減しながらも、コア機能に集中することができ、短時間で実装できました。   FastAPI バックエンドではFastAPIを使用しました。コードを書くだけでSwagger UIによりAPI文書が自動生成され、別途文書を作成する時間を削減できました。以前Flaskを使ったときより、APIを簡単に構築することができました。   AIの活用 今回の開発で、要件定義やAPI、DBの設計といった上流工程ではNotion AIを活用し、思考の整理やドキュメント化を高速化しました。 また、実装の部分ではClaude Codeを活用することで、コーディングに書ける時間を大幅に削減し、3日間という短い期間で効率的に開発を進めることができました。 開発終盤ではAIの出力結果に対してレビューが不足な部分があり一時的にアプリが起動しなくなる場面もありました。この経験から、AIの出力結果を鵜呑みにするのではなく結果の内容をレビューすることでAIのメリットを最大限活用することができることを学べました。   まとめ 今回のエンジニア定例合宿では、これまでの研修で培ったスキルだけでなく、初めて使用する技術やAIエージェントを最大限活用することができ、大変有意義なものとなりました。 会社の業務から離れて、3日間という短い期間の中で様々な技術を使って開発を進めることができた経験を糧に、今後の研修や業務で生かしていきたいです!
こんにちは。ニフティの長期インターンシップに参加した吉原です。 基幹システムグループ インフラシステムチームのサブチームである、社内プラットフォームチームに所属し、社内の情報システム担当の一員としてインターンシップに参加しました。 軽く私の自己紹介をしますと現在、情報系の学部3年生で1、2年生の時は計算機や数理モデリングなどを幅広く学習し、現在は暗号の理論や応用などを研究できる研究室に所属しています。 今回は3ヶ月間行った長期インターンシップを通して学んだことなどをまとめていきたいと思います。 ニフティの長期インターンシップを知ったきっかけ 4月に研究室に会社紹介でいらした OBの方のお話 を聞き、内製で開発をする割合が高いことや会社として成長を後押ししてくれる環境であるニフティという会社に興味を持ちました。 大学生になってから、将来はエンジニアとして働くという目標はあったものの、本格的な開発経験はゼロでした。そんな私がニフティの長期インターンシップに参加することになったきっかけは、夏休み前に 大学の掲示板に貼られていた一枚のポスター です。 「本格的な経験が積めるチャンスがある!」と強く惹かれました。 自身での開発経験がなかったため、長期インターンは正直「自分には難しい」と考えていました。しかし、「要件定義から設計、実装まで体験」という言葉に強く惹かれ、「受かったらラッキー」くらいの軽い気持ちで、ダメ元で応募してみたのが正直なところです。 実際に行ったこと 今回の長期インターンシップでは、主に社内システムに関わる複数の業務を経験させていただきました。 1. 分離されたネットワーク間でファイルをやり取りするツールのエンハンス このツールは社内のセキュリティレベルをまたぐファイルの移行を、安全に実行するためのツールです。もう少し具体的にいうと、 機密性の高いネットワーク と 一般的な業務ネットワーク の間で、ファイルを移行する際に「このファイルは移動しても良いか?」「移動先のセキュリティレベルで扱っても大丈夫か?」をチェックする役割を持っています。また、このチェックでDLP(データ損失防止)を使用しており、一部ファイルでは自動でチェックしてくれます。 このプロジェクトでは、主に TypeScript を用いて既存のツールに機能を追加するエンハンス作業に取り組みました。私自身、TypeScriptはインターンシップで初めて触れる言語でしたが、チームメンバーへの質問や生成AIを利用して、一からキャッチアップしながら開発を進めました。 エンハンスの背景と目的 として以下のユーザー課題を解決するため、具体的な機能追加を行いました。 ファイルの判別性向上のため、ファイルが多くなった際に、どれが最新か/古いものか判別しやすくする機能を追加。 利便性の向上として、ダウンロードの進捗状況が確認できるように表示機能を改善。 セキュリティのためのセッション切れによる自動ログアウトを、ユーザーに通知する機能を追加。 ファイルの拡張子を見て、自動チェックの対象外か判断して通知する機能の追加。 2. 検収作業と購入手続きの理解 納品物(成果物)やライセンスなどが、発注内容に沿っているかを確認する 検収作業 を体験しました。 所属したチームは社内システムの運用を行っているため、検収作業が必要不可欠なのです。 この経験を通じて、会社がものやライセンスを どういう流れで購入するのか という、組織運営における重要なプロセスを認識できました。 特に高額なものを購入する際には「 稟議 」が必要となることを知り、初めてその言葉と手続きの重みを知りました。 3. アカウント発行申請のサポート 社員の入社時・退社時に行うアカウント関連の手続きについて社員の方と一緒に対応しました。 この業務を通して、社員の入退社に伴う手続きや、社内で使用するドライブの管理など、社内プラットフォームチーム が担う広範な管理業務 を認識することができました。 仕事に取り組む上で意識したこと 未経験で参加したからこそ、業務に取り組む上で以下の3点を常に意識して行動しました。 仕事の目的を考える :目の前の作業をこなすだけでなく、その 一つ一つの仕事が何のために行われているのか という目的を考えながら取り組みました。これにより、業務の全体像やチームへの貢献度を理解する助けになりました。 自己解決能力と質問の質の向上 :チームメンバーに質問する際は、まず自分で生成AIなども活用して徹底的に調べ、 自分がどこまで理解できていて、どこがわからないのかを明確にした 上で質問することを徹底しました。この結果、インターンを始めてすぐは自分がした質問がなかなかチームメンバーに伝わらないことが多かったのですが、インターンが終わる頃には自分の質問がしっかりと伝わるようになりました。 現場の雰囲気をつかむ :真面目に業務に取り組む一方で、実際に働いている社員の方々の雰囲気や、チームの文化、働き方を間近で感じることも意識しました。これにより、チームとして大事にしていることと、将来自分が働いた時に、どんな現場で働きたいかのイメージが具体的につきました。 最後に 大学生活など様々なことと両立しながらの3ヶ月間の長期インターンシップは、私にとって非常に貴重な経験となりました。 インターンシップに参加する前、私は エンジニア=開発をする役割 というイメージしか持っていませんでした。しかし、実際に現場に入ってみると、私が体験したような 運用や保守、検収、各種申請対応など、開発以外にも多岐にわたる重要な業務 があることを知りました。 この経験を経て、今ではツールのエンハンスだけでなく、 システムを安定稼働させるための運用や保守 にも非常に興味を持ち始めています。未経験で飛び込んだこのインターンで得た知見と経験を活かし、これからもエンジニアとしての目標に向かって邁進していきたいです。
この記事は、リレーブログ企画「Maker Faire Tokyo 2025ボードゲーム制作リレーブログ」の記事です。 はじめに Maker Faire Tokyo 2025 に向けて、ボードゲーム「通信パンク」のカード用イラストを担当しました。この記事では、やったことや工夫したことをサクッと振り返ります。 ちなみに「アグロ」ってなに? 「アグロ」はカードゲームの用語です。低コストのカードで短期決着を狙うスタイルを指します。今回は工数とスピードを重視したので、「アグロ作画」と名付けました。 体制と役割分担 ポーズや全体デザインの提案:西野さん レイアウト、背景、配置、書体など:西野さん キャラクターの描き起こし(イラスト):ムサシ 担当をはっきり分けたおかげで、迷いが少なくて進みが速かったです。イラストに集中できたのが効きました。ありがとうございます! 表現方針:カードで映える「2〜3頭身」 カードサイズで“パッと可愛い”を狙って、2〜3頭身のデフォルメで統一。小さな面積でも情報が潰れにくく、視認性と個性のバランスが取りやすいのがポイントです。 制作プロセス(戻り少なめで一直線) 今回はこの順で進めました。初期に方向性を合わせたので、大きな差し戻しはほぼなし。 1. ラフ作成 2. チームで方向性の合意(ここでズレを解消) 3. 線画 4. 色塗り 5. 西野さんがカード用にデザイン調整(レイアウトや背景、配置など) 6. 最終チェック 目指すものがチームで一致していて、互いの専門性をリスペクトできていたのがスムーズさの理由でした。 ツールと制作環境 リモート期にセキュリティチームへ確認してペンタブの利用許可を取っていたため、自前の液晶タブレットで描きました。自宅は Windows、会社は Mac と環境が違っていて、しかも液タブは少し古めだったのでセットアップはやや大変でしたが、最終的には“慣れた道具”に寄せる判断が正解で、制作スピードをしっかり出せました。 これがあると助かるポイント どんなキャラクターか 性格、年齢感、世界観、参照イメージなどがあると精度が上がります どんなポーズ・シチュエーションか 表情やアクション、場面の意図が分かると初動が速いです この2点があるだけで工数がぐっと変わります。ラフや文字メモ、棒人間レベルでも伝わります。 かかり時間の目安(体感)|キャラクター指定の有無で変わる話 時間がかかる順はこんな感じです。 完全おまかせ デザインに指定あり(指定が多いほど短縮しやすい) 既存キャラクターの使い回し “完全おまかせ”は自由度が高いぶん、方向性合わせに時間がかかりがち。逆に指定が多いほど、往復が減って仕上がりのブレも小さくなります。 今回の判断:既存キャラクターを活用|キャラクター選定の理由 スケジュールがタイトだったので、既存キャラクター「BookBot ちゃんくん(としょだより、NIFTY Tech Book #1 にも登場)」を採用しました。 参考リンク 「としょだより」: こちら 「NIFTY Tech Book #1」: こちら (技術書典マーケットから無料DL可) メリット キャラクターデザイン案を決めるためのコミュニケーションの往復を短縮できる キャラクターデザイン側の微調整に他の時間を回せる 既にいるキャラクターなので、チーム内でイメージの整合がとりやすい 注意した点 「今回らしさ」をどこで出すかを先に決める 攻撃カードは悪そうにする 2Pカラーの差分を作る案もありました 直接的な表現ではなく間接的な表現にする 台風の影響で「トラフィックが遅くなる絵」ではなく、コミカルに「台風で困っている絵」を描く 配色、質感、目線の方向などの小さな差分でテーマの伝わり方が変わる 結果として、短期間でも統一感と読み取りやすさを両立できました。 おわりに 役割をクリアにして、最初に「キャラ」と「ポーズ・シチュエーション」をそろえる。ラフ段階で方向性を固めて、段階的に仕上げていく。これだけで制作はずっと滑らかになります。またカードを作ることがあれば、チームで速くて可愛い“カード映え”を積み重ねていきます。 次回はリレーブログ最終回、西根さんの「アイデアが”形”になるまでの物語。自作カードゲームの印刷からイベント出展までを振り返る」です!
概要 こんにちは。ニフティの山田です。 2025年10月21日に、Next.js 16がリリースされました。 https://nextjs.org/blog/next-16 大きな変更がそれなりにあるので、上記記事からピックアップしてみます。 破壊的変更点 ブラウザサポートのBaseline Widely Available基準への変更 Next.js 15からサポートブラウザが一気にバージョンアップしています。 Chrome Edge Firefox Opera Safari Next.js 15.5 64+ 79+ 67+ 51+ 12+ Next.js 16.0 111+ 111+ 111+ – 16.4+ これは単に上がったというだけでなく、 Web Platform Baseline におけるBaseline Widely Availableへの追従の結果としてこうなっています。 https://github.com/vercel/next.js/pull/84401  Widely Availableとなる要件は、主要ブラウザで30ヶ月以上利用可能であることです。 つまり、今後のNext.jsではメジャーバージョンアップのたびに 2.5年以上経過したブラウザは動作対象外 となることを想定する必要があります。 古いブラウザをサポートしたければ、 browserslistを設定してトランスパイルターゲットを変更 next.config.jsの transpilePackages で、クライアント側が使うライブラリをトランスパイル対象に追加 デフォルトではnode_modules以下はトランスパイル対象外となる… Fastly Polyfill などにより、トランスパイルで対応できない部分にPolyfillを追加 などの対応がより重要となってきます。特にpolyfillについて、Next.jsは独自に内蔵するpolyfillコードを使っているため、Next.jsサポート範囲外の対応には別のpolyfillコードを差し込まなければいけない点に注意が必要です。 middleware.ts → proxy.tsへの変更 middlewareの名前が変更となりました。 一般的にmiddlewareと呼ばれるものとは異なる機能であるため、わかりやすさのためにこうなったようです。 next lintコマンドの削除 以前のNext.jsでは eslint コマンドではなく、 next lint コマンドを利用してeslintを実行するのが推奨になっていました。eslint以外にもbiomeなどの選択肢が出てきたことから、この機能は削除となりました。今後は eslint コマンドを直接叩けばよいです。 なおNext.js 15.5の時点でdeprecatedになっていたので、そこで対応していれば問題ないはずです。 turbopackデフォルト化 バンドラとして従来使われてきたwebpackに代わり、ようやくturbopackがデフォルトとなります。 今まではturbopackを使用するのにCLIオプションが必要でした。 next dev --turbopack next build --turbopack 今後はturbopackがデフォルトとなり、逆にwebpackを使いたいときにのみオプションを指定する形となります。 next dev --webpack next build --webpack 新機能 Cache Components 今までExperimentalでPartial Pre-Rendering(PPR)やDynamicIOの名前で実装されていたものが正式版となります。 Next.js 13で導入されたApp Routerではキャッシュ制御が非常に重要になりますが、 fetch() がキャッシュ機能を持つものに暗黙的に置き換わるなど予測しにくい挙動をしていました。このため、Next.js 15でキャッシュのデフォルト無効化などの変更が行われる事態が発生しています。 そこで出来たのが新しい use cache によるキャッシュ制御です。以下はNext.js 16公式ブログから引用しています。 // File level 'use cache' export default async function Page() { // ... } // Component level export async function MyComponent() { 'use cache' return <></> } // Function level export async function getData() { 'use cache' const data = await fetch('/api/data') return data } use cache を記述することでキャッシュを有効化します。上記にあるように、記載位置によってファイルレベル・関数レベルでキャッシュ有効化単位を制御できます。 cacheLifeなど、キャッシュ時間を制御するための仕組みも増えました。 'use cache' import { cacheLife } from 'next/cache' export default async function Page() { cacheLife('hours') return <div>Page</div> } キャッシュの仕組みを変えることになるため、現状では設定しなければ有効になりません。 const nextConfig = { cacheComponents: true, }; export default nextConfig; おそらく今後はこちらを主流にしていくのではないかと思われます。 従来のキャッシュ制御も引き続き利用可能ですが、将来的にはどこかで移行することになるでしょう。 React Compiler対応 React CompilerはReactコードの最適化機能です。 https://ja.react.dev/learn/react-compiler ビルド時にコードを解析することで useMemo() や useCallback() などのメモ化コードを自動的に挿入し、レンダリングの最適化を行います。開発者はメモ化のことを意識しなくて良くなる、という機能です。 これがNext.jsでも使えるようになりました。 対応するには設定を加えたうえで const nextConfig = { reactCompiler: true, }; export default nextConfig; React Compilerのインストールが必要となります pnpm add -D babel-plugin-react-compiler 注意点として、React Compilerは babelプラグインとしての提供 となることが挙げられます。SWCで実行されないので、ビルドが遅くなる可能性が高いことに注意が必要です。 おわりに 今回は、2025年10月21日にリリースされたNext.js 16がリリースについて解説しました。 参考になれば幸いです。
はじめに こんにちは!新卒1年目のなべしま、宮村、坂野です。 ニフティでは、毎年新人育成の一環として「エンジニア定例」や、3日間にわたる開発合宿「エンジニア定例合宿」が行われています。 今回は、この「エンジニア定例合宿」で私たちが作成したアプリケーションを紹介します。 実際の合宿の様子や食事、成果報告会についてはこちらに載っていますので、ぜひご覧ください! 今年はいつもと違う?ハッカソン合宿に行ってきました!@マホロバ・マインズ三浦 メンバー紹介 メンバーはこの3人です。動物(生き物)好きが多い気がします。 なべしま ダイアウルフかわいい 宮村 クラゲにハマっている 坂野 マヌルネコが好きすぎる アプリ紹介 概要 私たちは、食材管理とレシピ提案を統合したWebアプリケーションを作成しました。 主な機能として、AIが冷蔵庫の食材からレシピを自動提案する機能や、料理と連動した食材の自動消費管理機能などがあります。 アプリ画面・特徴 冷蔵庫画面 冷蔵庫内の食材がパネルとして整列しており、ここから直感的に材料の個数や量、消費期限の登録ができます。 このページはログイン必須で、冷蔵庫の中身はユーザーごとに独立しています。また、ユーザーがログインしていない場合は、Keycloakのログイン画面にリダイレクトされます。 レシピ詳細画面 材料の分量一覧と作り方を表示しています。 下の「材料を消費」ボタンを押すと、冷蔵庫の中身が、賞味期限が早いものから順に材料分だけ消費されます。 AIおすすめ機能 冷蔵庫の材料から、おすすめのレシピを提案します。 生成された料理名をクリックすると、レシピ詳細ページへ移動します。 使用技術 今回採用した技術スタックは以下の通りです。 これらを選定した理由としては、フロントエンドとバックエンドに分離しないシンプルなフルスタックアプリケーションにすることで、タスクの属人化や環境構築、学習コストを最小限に抑えることなどがあります。 アプリケーション: Next.js , Prisma , NextAuth.js データベース: PostgreSQL 認証基盤: Keycloak その他 : Amazon Bedrock (Claude Sonnet 4.5) そして、環境構築の時間を短縮するため、アプリケーションのベースには、社内プロジェクトである、 NIFTY Programming Best Practices(PBP) のNext.jsリポジトリを使用しました。 NIFTY Programming Best Practices(PBP)とは 開発のベストプラクティスを集約するProgramming Best Practicesプロジェクトです PBPは技術毎にベストプラクティスをドキュメントやテンプレートとして集積を行っており、標準化はどの技術を社内標準とするか決定しています。 社内ナレッジ NIFTY Programming Best Practices(PBP) 開発の流れ 1日目: 環境構築とプロジェクト設計 環境構築 、データベース設計 (午後) PBPを用いた初期のフロントエンド環境の構築 Claude Code Action の導入 Keycloak の導入 Prisma を用いたデータベースのセットアップとテーブル設計 タスクの具体化 (夕方) 実装すべき機能の具体化とタスクの洗い出し 2日目: 環境設定の最終調整とフロントエンド・認証機能の実装 環境構築の仕上げ (午前) Keycloak のRealm作成などの環境設定 データ投入、UI・認証機能の実装 (午後) レイアウト、メニューバーといったUI周りの実装 ログイン機能の実装 デモに必要なサンプルデータを追加 レシピ、冷蔵庫のビジネスロジックの実装 「冷蔵庫の中身からおすすめする機能」に関する調査、実装 最終日: 主要機能の仕上げと成果発表に向けた資料作成 機能実装の完了、AWS 整備 (午前) 未完了だったビジネスロジックの実装 CDパイプラインの構築やビルドプロセスの修正 発表資料の作成 (午後) 機能実装と並行して、 Marp を用いた発表資料の作成 開発工程でのGoodポイント Keycloakの利用によるユーザ管理の責務の分離 ユーザー管理の実装負荷や、その責務をWebアプリケーションから分離することを考え、外部IdPを利用する方針で進めていました。Amazon Cognitoを使用する予定でしたが、ローカル環境でのテストを考慮した結果、採用は見送りました。結果として、IdP側はKeycloak、認証ライブラリ側はNextAuth.jsを使用しました。この二つの連携や実装に関する情報はかなり豊富で、開発を円滑に進めることができたと感じています。 Claude Code / Claude Code Actionの活用 今回の開発では、Claude Code Actionを活用して人間のコーディング量を最小限に抑えることを目指しました。設計段階でMermaidで作成したER図をもとに、モデルファイルと関連する環境構築まで終わらせることができました。一方で、CIの修正の自動化やGitHub Actionsの権限の修正・調査に時間をかけられず、終盤まで活用し切ることはできませんでした。 常に情報共有を行い、最後まで挑戦し続けた 合宿の3チームの中で、雑談からカンバンのタスク内容や構造に関する議論まで、最も活発なコミュニケーションが行われたチームだと感じています。この常に共有する姿勢が、高いチーム結束力を生み出し、最後まで一丸となって課題に挑戦し続ける原動力になりました。 まとめ 今回は、3日間のハッカソンで開発したアプリケーションを紹介させていただきました。 AWSへのインフラ構築は残念ながら時間不足で実現できませんでしたが、認証機能の実装や環境構築など、実務にも活きる要素を利用した開発はとても良い経験となりました。また、これらを活用した開発や、チーム一丸となって取り組む姿勢は、今後の業務でも継続していきたいと感じました。 一方で、初めて使う技術の知識不足や、入念な設計の必要性など、自分たちの課題も認識できました。 合宿で得た経験を、これからの業務に活かしていけたらと思います!
この記事は、リレーブログ企画「Maker Faire Tokyo 2025ボードゲーム制作リレーブログ」の記事です。 記事の概要 ボードゲーム部がオリジナルカードゲームをつくるまでの道のりを紹介します。カードデザインの裏話も交えます。 はじめに ニフティには「ブカツ制度」があります。私が所属するのはボードゲーム部は、市販のゲームを持ち寄って遊ぶシンプルで楽しいブカツです。 ある日、Maker Faire Tokyo 2025 の推進メンバー寺島さんが自作ゲームを持参してくれました。イベントなどで個人制作のゲームをみることはありましたが、「自分でも作れるんだ」と実感したのはこの瞬間でした。 ISPでカードゲーム? 数ヶ月後、Maker Faire Tokyo 2025 のニフティブースでオリジナルカードゲームを出そう、という話が始動します。ボードゲームは大好きですが、制作経験はゼロです。それでも「せっかくならやってみよう」と手を挙げました。 私は大学でデザインを学んでいたので、デザインまわりと初期ルール作成を担当しました。 ボードゲーム部でISPをテーマに募られたゲームのアイデアは大盛り上がりし、トークン(コマ)も自作できるのでは? と夢が膨らむ時期でした。 今見ても結構おもしろかったので、メモを残しておきます。 HTTPステータスコードかるた(かるたは既存のものがかなりあるので頓挫しました) ネットワークの配線 サーバー運用 ニフティサーブをテーマにしたコミュニケーションゲーム スクラムのPBI分割をゲーム化 「22」と「パケット」をテーマにデザイン 検討の結果、既存ルールの発展形が進めやすいと判断しブラックジャックをベースにしました。 ブラックジャックは到達値が21です。けれどニフティといえば 22。これはニ(2)フ(2)ティの語呂です。 毎月「2」の日や「22」日はニフくじが当たりやすい ので、覚えておいてください! テーマは「通信・トラフィック」。当初見積もりしていた納期が短期間だったため、ルール作成と並走でデザインを進めます。 裏面 初期案 「22」の中にカタカナの「ニフ」を入れ込んでいます。収まりが良く、ほぼこのまま採用しました。 表面 初期 テストプレイ用に、ムサシさんの既存イラストを仮素材で拝借しています。初期案では「数字を分割する」要素が一部残っていますね。 テストプレイは、元ネタがブラックジャックなのでトランプの代用で十分でしたが、そのおかげで、表面の情報が少ないことに気づき、役札へフレーバーテキストを入れる方針を前倒しで決められました。 表面のデザイン詰め 数字フォントを大きく置くだけでは間が持たなかったため、数字自体をデザインしています。数字は、デジタル感とパケットの粒感をイメージし、丸いドットでの構成にしました。 席の隣でムサシさんがラフを描いてくれていたので、役札に絵を当て込んだ瞬間「かわいい!」「カードゲームっぽい!」とその場で盛り上がりを共有できました。 数字のデザインは、数が大きくなるほどパケットの色味を増やし、トラフィックの混雑感を視覚化しています。 数字に関する社内フィードバックでは、 6 と 9 が判別しづらいという意見があり下線を追加して視認性を改善しています。 この段階でプリントしてカードサイズに切り、フレーバーテキストなど文章の可読性のチェックもしました。 こういった制作の進捗は Slack でこまめに共有し、リアクションなどで即フィードバックをもらいました。通常業務と並走しながらも、テンポよく前に進めたと思います。 入稿 カード 1 セット分の画像を量産するため、共通オブジェクト(インスタンス化)して配置しています。後からの編集もしやすくてラクでした。 トンボなど入稿要件は印刷会社に確認し、一次入稿でチェックを受け、最終までスムーズに運びました。 ロゴとパネル ブースにルールを書いたパネルも出すことになったため、ロゴとパネルを追加で制作しました。 文章はプロジェクトをリードしてくれた西根さんに依頼し、レイアウトを担当しています。 今回はパッケージがなくロゴの出番は少なめなので、終盤に一気に仕上げました。 ロゴの配色はカード表面と合わせ、統一感をだしています。 やってよかったこと 途中段階でも共有とレビューをしたことで、齟齬や手戻りを最小化 画像は PNG形式で共有ドライブに格納し誰でも扱える状態にし、つくりものの全体トーン統一 イラストとデザインの担当者が分かれていたが、一緒に作業してラフが出た時点でカードに当て込みをし、出来上がりのイメージを共有 最後に 印刷が上がった瞬間以上に、ブースで来場者が楽しそうにプレイしている姿は別格の喜びがありました。「遊ぶブカツ」から「作れるブカツ」へ、ひとつ階段を上れた気がします。 普段はスクラムマスターですが、久々に紙のデザインに向き合えたことも楽しかったです。 Maker Faire Tokyo 2025 はクリエイターのお祭りです。ニフティのクリエイティブな部分を、このカードゲームから少しでも感じてもらえていたら嬉しいです。 次回は、イラスト担当・ムサシさんの「イラスト制作:アグロ作画で可愛さ確定」をお届けします。