Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GA v1♭] [NOTES] TODO() by duangsuse #11

Open
9 of 17 tasks
duangsuse opened this issue Feb 1, 2019 · 23 comments
Open
9 of 17 tasks

[GA v1♭] [NOTES] TODO() by duangsuse #11

duangsuse opened this issue Feb 1, 2019 · 23 comments
Assignees
Labels
designment Designment errors for GeekApk help wanted Extra attention is needed v1♭ GeekApk first version wontfix This will not be worked on

Comments

@duangsuse
Copy link
Collaborator

duangsuse commented Feb 1, 2019

TODO

https://github.com/bjzhou/Coolapk-kotlin

  • TravisCI integration support
  • AppType
  • Add getXXXXCount() Interfaces for client update event check
  • QCL interpreter (v1.1b)
  • Add platform task for GeekApk pictures(copycat 🐱
  • GeekApk i18n
  • User last-online-at time
  • App pinned comment
  • Test driven development
  • Add GET Views for non-GET APIs (debug view) (v1.1b)
  • Add PATCH (Bulk update entity properties) APIs (v1.1b)

TODO later

  • Topics like CoolApk(yes, with 'subscribe' feature) (merging extra timeline)
  • MessageHeader specification (At mentation user, join topics...)
  • Make a built-in GeekWidget plugin replacing coolapk's App discovery
  • GeekPush & support user (cross device) push events (server-side interface for cloudInstall)
  • Database migrate program
  • Support J2EE servlet containers arithetcute (v2)

"NOT" TODO

  • App discovery like CoolApk

WHY: GeekApk Users can create apps on their purpose, and GeekApk have a GeekWidget plugin replacing coolapk's App discovery (inline picture in comments)

  • favorite comments(o:feeds) (designment reasons)
  • (un)recommend(+1) comments (designment reasons)
  • Headline like CoolApk (Badges in GeekApk actually the same)
  • App QR Code
  • Recommended Apps and Albums (AppDeps in GeekApk will "implement" that)
  • Avatar/Other Image storage (Use external services like sm.ms instead)
  • PM like CoolApk (GeekStream in v2 provides "PM" feature)
  • download stat (but, GeekApk Hits is almost the same...)
  • rating for apps (star is enough)
  • "Feed"s (GeekApk uses MetaApp to combine a "Feed Area" with its users)
  • pictures (Already has one)
  • App gift codes
  • block users on the server side
  • App tags (GeekDeps...)
@duangsuse duangsuse added help wanted Extra attention is needed wontfix This will not be worked on labels Feb 1, 2019
@duangsuse duangsuse self-assigned this Feb 1, 2019
@duangsuse duangsuse added the designment Designment errors for GeekApk label Feb 1, 2019
@duangsuse duangsuse changed the title [NOTES] TODO() by duangsuse [GA v1b] [NOTES] TODO() by duangsuse Feb 2, 2019
@duangsuse duangsuse changed the title [GA v1b] [NOTES] TODO() by duangsuse [GA v1♭] [NOTES] TODO() by duangsuse Feb 2, 2019
@duangsuse duangsuse added the v1♭ GeekApk first version label Feb 2, 2019
@duangsuse
Copy link
Collaborator Author

cup

@duangsuse
Copy link
Collaborator Author

目前 GeekApk 的控制器路径模板已经在 add-controller-template 分支上开发

填充完所有模板并合并到 master 后,下一个目标 branch 是 add-controller-tests

其时 v1b 的第一个版本所有非控制器的编程需求都没有了(因为之前都写完了,感谢 SpringBoot 使得我不用写那么多难看并且耗时间的 XML 配置文件),接下来就是测试驱动编程 implement-interfaces 喽

Test-driven development 的一个好处就是出来的肯定是能用的成品,因为它通过了验收测试(Acceptance test)

然后就是写前端

@duangsuse
Copy link
Collaborator Author

[DuangSUSE@duangsuse]~/文档/geekapk_spring% node code_writer.js

serverDetail() -> object:detailMap
= /serverDetail

serverVersion() -> plain
= /serverVersion

serverDescription() -> plain
= /serverDescription

serverBoot() -> datetime
= /serverBoot

POST@createUser(username:String) -> object:GeekUser
= /admin/makeUser

PUT@resetSharedHash(uid-path:UserId, shash:String?) -> plain
= /admin/resetMetaHash/{uid}

DELETE@deleteUser(uid-path:UserId) -> object:GeekUser
= /admin/dropUser/{uid}

PUT@flagUser(uid-path:UserId, flag:Int) -> object:GeekUser
= /admin/flagUser/{uid}

POST@createCategory(name:String) -> object:Category
= /admin/makeCategory

PUT@renameCategory(id-path:CategoryId, name:String) -> object:Category
= /admin/nameCategory/{id}

DELETE@deleteCategory(id-path:CategoryId) -> object:Category
= /admin/dropCategory/{id}

DELETE@deleteApp(aid-path:AppId) -> object:App
= /admin/dropApp/{aid}

PUT@transferAppCategory(aid-path:AppId, cid:CategoryId) -> [$aid:number, $old:number, $new:number]
= /admin/moveApp/{aid}

PUT@transferAppOwner(aid-path:AppId, uid:UserId) -> [$aid:number, $old:number, $new:number]
= /admin/transferApp/{aid}

DELETE@deleteAppUpdate(aid-path:AppId, rev-path:Int) -> object:AppUpdate
= /admin/dropAppUpdate/{aid}/{rev}

DELETE@deleteComment(cid-path:CommentId) -> [$cid:number, $deletedSubComments:number]
= /admin/dropComment/{cid}

categoryList() -> array:Category
= category/all

categoryName(id-path:CategoryId) -> plain
= category/{id}

readUser(id-path:UserId) -> object:GeekUser
= user/{id}

updateUser(id-path:UserId, prop:String, value-body:String) -> object:string
= user/{id}

resetHash(id-path:UserId, shash:String, hash:String) -> object:string
= user/{id}/hash

checkHash(id-path:UserId, hash:String) -> object:string
= user/{id}/checkHash

listUser(sort:String?, sliceFrom:UserSize?, sliceTo:UserSize?) -> array:GeekUser
= user/all

listMetaUser(sort:String?, sliceFrom:UserSize?, sliceTo:UserSize?) -> array:GeekUser
= user/allHasMetaApp

searchUser(type:String?, kw-path:String, sort:String?) -> array:GeekUser
= user/search/{kw}

updateOnlineTime(id-path:UserId)
= user/{id}/online

[ { method: 'GET',
name: 'serverDetail',
args: [],
return: { type: 'object', of: 'detailMap' },
url: '/serverDetail' },
{ method: 'GET',
name: 'serverVersion',
args: [],
return: 'plain',
url: '/serverVersion' },
{ method: 'GET',
name: 'serverDescription',
args: [],
return: 'plain',
url: '/serverDescription' },
{ method: 'GET',
name: 'serverBoot',
args: [],
return: 'datetime',
url: '/serverBoot' },
{ method: 'POST',
name: 'createUser',
args: [ [Object] ],
return: { type: 'object', of: 'GeekUser' },
url: '/admin/makeUser' },
{ method: 'PUT',
name: 'resetSharedHash',
args: [ [Object], [Object] ],
return: 'plain',
url: '/admin/resetMetaHash/{uid}' },
{ method: 'DELETE',
name: 'deleteUser',
args: [ [Object] ],
return: { type: 'object', of: 'GeekUser' },
url: '/admin/dropUser/{uid}' },
{ method: 'PUT',
name: 'flagUser',
args: [ [Object], [Object] ],
return: { type: 'object', of: 'GeekUser' },
url: '/admin/flagUser/{uid}' },
{ method: 'POST',
name: 'createCategory',
args: [ [Object] ],
return: { type: 'object', of: 'Category' },
url: '/admin/makeCategory' },
{ method: 'PUT',
name: 'renameCategory',
args: [ [Object], [Object] ],
return: { type: 'object', of: 'Category' },
url: '/admin/nameCategory/{id}' },
{ method: 'DELETE',
name: 'deleteCategory',
args: [ [Object] ],
return: { type: 'object', of: 'Category' },
url: '/admin/dropCategory/{id}' },
{ method: 'DELETE',
name: 'deleteApp',
args: [ [Object] ],
return: { type: 'object', of: 'App' },
url: '/admin/dropApp/{aid}' },
{ method: 'PUT',
name: 'transferAppCategory',
args: [ [Object], [Object] ],
return: [ [Object], [Object], [Object] ],
url: '/admin/moveApp/{aid}' },
{ method: 'PUT',
name: 'transferAppOwner',
args: [ [Object], [Object] ],
return: [ [Object], [Object], [Object] ],
url: '/admin/transferApp/{aid}' },
{ method: 'DELETE',
name: 'deleteAppUpdate',
args: [ [Object], [Object] ],
return: { type: 'object', of: 'AppUpdate' },
url: '/admin/dropAppUpdate/{aid}/{rev}' },
{ method: 'DELETE',
name: 'deleteComment',
args: [ [Object] ],
return: [ [Object], [Object] ],
url: '/admin/dropComment/{cid}' },
{ method: 'GET',
name: 'categoryList',
args: [],
return: { type: 'array', of: 'Category' },
url: 'category/all' },
{ method: 'GET',
name: 'categoryName',
args: [ [Object] ],
return: 'plain',
url: 'category/{id}' },
{ method: 'GET',
name: 'readUser',
args: [ [Object] ],
return: { type: 'object', of: 'GeekUser' },
url: 'user/{id}' },
{ method: 'GET',
name: 'updateUser',
args: [ [Object], [Object], [Object] ],
return: { type: 'object', of: 'string' },
url: 'user/{id}' },
{ method: 'GET',
name: 'resetHash',
args: [ [Object], [Object], [Object] ],
return: { type: 'object', of: 'string' },
url: 'user/{id}/hash' },
{ method: 'GET',
name: 'checkHash',
args: [ [Object], [Object] ],
return: { type: 'object', of: 'string' },
url: 'user/{id}/checkHash' },
{ method: 'GET',
name: 'listUser',
args: [ [Object], [Object], [Object] ],
return: { type: 'array', of: 'GeekUser' },
url: 'user/all' },
{ method: 'GET',
name: 'listMetaUser',
args: [ [Object], [Object], [Object] ],
return: { type: 'array', of: 'GeekUser' },
url: 'user/allHasMetaApp' },
{ method: 'GET',
name: 'searchUser',
args: [ [Object], [Object], [Object] ],
return: { type: 'array', of: 'GeekUser' },
url: 'user/search/{kw}' },
{ method: 'GET',
name: 'updateOnlineTime',
args: [ [Object] ],
return: null,
url: 'user/{id}/online' } ]

GET /serverDetail: serverDetail()
Returning object of detailMap

GET /serverVersion: serverVersion()
Returning plain

GET /serverDescription: serverDescription()
Returning plain

GET /serverBoot: serverBoot()
Returning datetime

POST /admin/makeUser: createUser(username:String!)
Returning object of GeekUser

PUT /admin/resetMetaHash/{uid}: resetSharedHash(uid-path:UserId!,shash:String?)
Returning plain

DELETE /admin/dropUser/{uid}: deleteUser(uid-path:UserId!)
Returning object of GeekUser

PUT /admin/flagUser/{uid}: flagUser(uid-path:UserId!,flag:Int!)
Returning object of GeekUser

POST /admin/makeCategory: createCategory(name:String!)
Returning object of Category

PUT /admin/nameCategory/{id}: renameCategory(id-path:CategoryId!,name:String!)
Returning object of Category

DELETE /admin/dropCategory/{id}: deleteCategory(id-path:CategoryId!)
Returning object of Category

DELETE /admin/dropApp/{aid}: deleteApp(aid-path:AppId!)
Returning object of App

PUT /admin/moveApp/{aid}: transferAppCategory(aid-path:AppId!,cid:CategoryId!)
Returning number:aid,number:old,number:new

PUT /admin/transferApp/{aid}: transferAppOwner(aid-path:AppId!,uid:UserId!)
Returning number:aid,number:old,number:new

DELETE /admin/dropAppUpdate/{aid}/{rev}: deleteAppUpdate(aid-path:AppId!,rev-path:Int!)
Returning object of AppUpdate

DELETE /admin/dropComment/{cid}: deleteComment(cid-path:CommentId!)
Returning number:cid,number:deletedSubComments

GET category/all: categoryList()
Returning array of Category

GET category/{id}: categoryName(id-path:CategoryId!)
Returning plain

GET user/{id}: readUser(id-path:UserId!)
Returning object of GeekUser

GET user/{id}: updateUser(id-path:UserId!,prop:String!,value-body:String!)
Returning object of string

GET user/{id}/hash: resetHash(id-path:UserId!,shash:String!,hash:String!)
Returning object of string

GET user/{id}/checkHash: checkHash(id-path:UserId!,hash:String!)
Returning object of string

GET user/all: listUser(sort:String?,sliceFrom:UserSize?,sliceTo:UserSize?)
Returning array of GeekUser

GET user/allHasMetaApp: listMetaUser(sort:String?,sliceFrom:UserSize?,sliceTo:UserSize?)
Returning array of GeekUser

GET user/search/{kw}: searchUser(type:String?,kw-path:String!,sort:String?)
Returning array of GeekUser

GET user/{id}/online: updateOnlineTime(id-path:UserId!)
Returning noting
[DuangSUSE@duangsuse]~/文档/geekapk_spring%

@duangsuse
Copy link
Collaborator Author

找到了个很有意思的名词:Dao(Data Access Object)
是这样的么?

@duangsuse duangsuse pinned this issue Feb 5, 2019
@duangsuse
Copy link
Collaborator Author

screenshot_20190205_232310
Branch "add-tests" excluded per configuration.

@duangsuse
Copy link
Collaborator Author

screenshot_20190205_232030
贡献者 duangsuse 已经启用很无聊的 Commit GnuPG 签名,除了让 GitHub 开心外没有什么卵用。

@duangsuse
Copy link
Collaborator Author

screenshot_20190205_211709
百 Commit 纪念

@duangsuse
Copy link
Collaborator Author

Travis GitHub App Installed 🔧

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 5, 2019

[In reply to duangsuse::Echo]
git diff --stat fb0242a abb5d6c

11 files changed, 343 insertions(+), 34 deletions(-)

在半个小时里,GeekSpec 自动生成了 300 多行模板代码,换算成人就是十分钟写 100 行啊,都是这种代码:

  @PutMapping("/{aid}")
  @ResponseBody
  fun updateApp(@PathVariable("aid") aid: AppId, @RequestParam("attr") attr: String/* Maybe package or icon or name or screenshots or readme */,
                @RequestBody value: String): Map<String, String> /* attr: String *//* oldVal: String */ {
    TODO()
  }

不无聊么?
上面的代码,为什么不可以这么写呢?

PUT@updateApp(aid-path:AppId, attr:String{package, icon, name, screenshots, readme}, val-body:String)
  -> [$attr:String, $oldVal:String]
= /app/{aid}

于是我居然花了一天时间弄了个 GeekApk 自己替换 Swagger 的,虽然没啥复杂算法... 但不得不说,真的很有用。
『磨刀不误砍柴工』

... CS 看多了又想到偏序理论... 头疼

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 5, 2019

screenshot_20190206_000441
🤔 GeekSpec 对 GeekApk Spring 的工程有多大的辅助作用呢?自 Spec 文件写完 fb0242a 之后,自动生成解决了 300 多行模板代码的编写任务,从写完 7:34 到完成任务合并主分支 8:08 只花费了半个小时左右,可谓是一瞬生成了(

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 8, 2019

哇,除了 DAO,我又认识了一大堆那么专业的术语名词,听起来真是好大佬呢,好厉害呢!不明觉厉呢!哇!原来这就是 IT 啊,我要打十个!

MVC、MVP、MVVP、Databinding、ViewHolder、AOP、Provider、Resolver、Adaptor、Pattern、List 视图、PAJAX、AJAX、Reverse AJAX、Bean、CDI、Transactional、ACID、Functional、GC、Memory Leak、static field、obfuscation、anti-reversing、Machine learning、解耦合、Component、POJO、DSL、Parametric Types、Encryption、Cipher、Observer、Stream、Future、Dependencies、Box Model、Dispatcher、Handler、Scheduler、OOP、FP、Xml

SICP、TaPL、FoPL、CSAPP、SASP、…

你们说我是不是可以去写十个酷安了?(笑)

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 8, 2019

  • 那么多人用 J2SE 的 UUID 类,你为什么不用,非得自己写?是不是你连 JSE 有这个都不知道?

懒得用,因为我觉得不好看、不是。因为酷安的 API 客户端验证就用到了此类、DDG 上一搜全都是,并且我也看过 Oracle 的文档,我不可能看不到。实际上我妄图写了点 Kotlin/multiplatform 代码都用到了此类。

  • 为什么不用 MongoDB?

PostgreSQL 更成熟,而且我们的建模是关系型的,目前没有 lower 化模型的打算
芒果数据库(不准喷翻译)是文档型数据库,其实它这个接口很适合熟悉 Java collections API 的程序员使用。我们说关系的本质是图,但是图在电子计算机上往往使用 Map 和 (对于每个节点之间关系箭头的建立)Set 来构建。MongoDB 提供了易用的 API。
GeekApk 的模型很大,我很难一次做好(是的,即使我出过很多版本的文档)
不像隔壁,它的模型就比较简单(是的,而且他们用的 service 层又是别的… 我们为了速度先用的是手里有包含实际例子的 SpringBoot。 LBA 架构么?总是说术语… 无聊,而且这就像拼音和五笔一样,明明都差不多,各有所好因为各种有不同的经历)

  • Authorization (token, updated) (不是 DO)
  • Category (key, name(sizeIn = [0, 12)), rank: Int(max = 66536), owner: User, created, updated)
  • Failure (message) (这个不是 Domain model)
  • Feed (key, title, content, category: Category, owner: User, url, cover_url, created)
  • User (key, name, description, password, email, authorization, created)

要喷这个,请大人您先考虑一下 GeekApk v1b 的模型,和上面那个比起来哪个大。注意我们(GA Spring 和 Rebase-server)的权限验证都没有用外部的 CDI 库。

  • SpringBoot 包装了那么多复杂度、Persistent 层、Serialization、Validation 等都包含,而隔壁 Rebase server 都是自己的,你不自卑?
  1. 我把自己当少爷,懒得管那些低层机械化的任务和模板代码,让 Spring 帮我弄不是提高效率么(再说一定要写现在资料也不难查,我也有 Internet 的教科书
  2. 我要卖小、我才 17 岁,隔壁那个 13 年入 gh 的老油条了,而且 when 隔壁已经发布能用的第一版 0.9,我 17 年 1 月才会写很模式化的 Java,而且我看不透后面那些东西,非常幼稚 naïve 并且啥算法不会写。我写这个的时候刚刚接触软件工程两年。拿一个至少 4 年经验而且专攻 JVM 工程的老油条你们良心上过得去么?我还只是个孩子所以请不要拿资深全栈吊打我 小心我成资深后端了回来各种吊打你们
  3. 再不说,本项目刚开 7 天,不算我没写代码(比如走亲戚和修整)的总共才开 4 天,隔壁那个从 Hello world 到第一个 release 0.9 就从 Jan 14..Jan 21 已经有至少(减去休息一天 6 天时间),老项目了。(迫真)
  4. 我这个开源的,说明我不把它当回事,隔壁那个源代码删了,说明隔壁很觉得此作怎么样(注意诡辩)
  5. 瘦死的骆驼比马大啊… 这些基本看完就会整个源代码里没几个类引用的东西,比起函数式编程、信号处理、编译原理的一些书论文文章,哪个更困难?哪个更需要脑子而不是死记?

不说那些基本就是非常简单的 proxy (和设计模式无关) extract 的东西(比如那些单纯包装外部 procedure 的类、静态方法、静态字段)了,咱看看这个:

@Constraint(validatedBy = { CategoryKey.Validator.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface CategoryKey {

    int min() default 1;

    int max() default Globals.SIZE_CATEGORY;

    String message() default "{org.hibernate.validator.constraints.Length.message}";
// Validator implementation omitted

80% 的模板代码,而且三个文件中可以说这些代码都是重复的。我看一遍这些模板代码使用的接口也就大概了解了,请问这算什么?不算 Java 8 语法的部分,我只需要知道 @Constraint(validatedBy: Class<?>[]) min max message org.hibernate.validator.constraints.Length.message Class<?>[] groups() Class<? extends Payload>[] payload() Validator implements ConstraintValidator<CategoryKey, String> { initialize (annotation); boolean validate/*update: isValid*/(value, context); },就算学会了这知识。何况 IDEA 现在那么方便,应该比谁更会用特性和快捷键(e.g. Ctrl N)才是。

我看完这些就是满脑子名词,Resources、Provider… XXXXs、YYYYMapper…
然而,比起理解递归、解决各种动态规划甚至线性代数问题,这些接口了解性质的东西真的可谓是『了解』而不能算作是学习… 这点概念哪里配得上『学习』这个词… 配得上机器学习里的学习这个词

  • 为什么你要去看别人的代码

我很心虚,觉得自己的代码不好,就去看别人的取长补短。我是菜🐔别人是大佬不行吗?

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 8, 2019

* 那么多人用 J2SE 的 UUID 类,你为什么不用,非得自己写?是不是你连 JSE 有这个都不知道?

....

行了... 好无聊啊,其实要看的话,要比较的话也没有可比性,那个设计模式更多一些(),但它不能证明什么,因为这些代码也可以抄,目前本项目的代码都是我抄书上抄来的。

我目前的任务就是弄完 GeekApk,其他的再说。

duangsuse 有时候会有点神经质,因为我对技术看得太重... 如有不便还请大家谅解。刚才想要不要彻底分析一下刚才那个项目,顺便熟悉一下工程的说(因为我平时工程做得比较少,可以作为一种提升,虽然也模式化但比这个 Spring 的稍微好一点),可是因为 GA 最好还是先弄完(包括前端)就算了。

🙏 👦

@duangsuse
Copy link
Collaborator Author

https://github.com/Codingpedia/demo-rest-jersey-spring

emmmm DataAccessObject 和 Entity 居然不是一样的 🤔 #Backend #web

不过我现在几乎没有看到 DAO、大概是后端的书不够多...

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 10, 2019

https://github.com/imufun/rebase-server/tree/master/src/main/java/com/drakeet/rebase/api/tool

我已经正常分析了此项目并且理解了所有 Extracts(Authorizations, Globals, Hashes, Log, MongoDBs, RebaseAsserts, Responses, URIs)、Mapper(ConstraintViolationExceptionMapper, WebExceptionMapper)、Provider(GsonBodyProvider)、Resolver(ValidationConfigurationContextResolver)、Implementation(ObjectIdSerializer)... 还有他们自己的用途、模式、运行时的数据流和控制流,并和我之前的知识相结合,并且在正常的时间内完成,不会崩坏了。thx。GeekApk 会照常以自己的风格完成开发。

@duangsuse
Copy link
Collaborator Author

since 目前我写了第一个含写的接口业务逻辑测试,结果写了半天 200 多行代码... 而且很多代码... 呃... 很难看,因为 JUnit 的原因,貌似没办法保持一定顺序执行(因为我这个是要求某些操作顺序的,之间互相有依赖关系),而且这个测试质量很差... 而且单独去给所有接口写测试是非常淡疼的。我决定写保护 add-tests 分支,跳过测试编写,直接开始编写业务逻辑。而且我希望尽快完成任务,,, 所有 v1b 的 Boot Server 可能不会弄 test-driven development,emmm....

58a32fb 割肉删掉了测试.. 以后自动化测试会由 Ruby 执行

@duangsuse
Copy link
Collaborator Author

♥\_(ㇱ)_/✐ 👈 疯狂暗示用爱写代码 hhhh 🤣

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 10, 2019

Ruby 的 Spectrum 打算先暂时 JSON,因为我最近有点... 不想写 Ruby?
其实是嫌浪费时间了

@duangsuse
Copy link
Collaborator Author

[ Photo ]
累死,算是学习(确信)了一下 Ruby 和测试了 Spectrum... 感觉解耦合做得不是很好,response mapper 根本一点用都没有(因为要很多 mapper 必须要拿到一个 ClientShowcase 实例),另外给 ClientShowcase 添加一个 Hash 表来放诸如密码这样的东西隐式传递不错),考虑重构。

@duangsuse
Copy link
Collaborator Author

[In reply to duangsuse::Echo]
Times 是之前老 GeekApkR 里唯一一个能用的后端服务... Ruby + Sinatra 写的,其实现在看来都很不良实践(跑)
凑字数(代码行数)吧(

不过它的测试套件也算完整,虽然持久化层的不是 Mock,但也可以用,缺点是如果在生产环境用了很可能导致数据丢失

Times 没有使用 DBMS,而是,这是因为我以为它不会有太大的数据集性能要求,我觉得很可以重构(比方说,使用类似 MongoDB 的面向文档数据库替换纯手动)... 尤其是难看的 API...

值得注意的是我以前智商还低一些的时候,连常用的序列化这种弱智能力都没有...
JSON 序列化(Times 的数据持久化方式)当时非常的混乱,我非常智障的套模板(或许,因为我想我那时就是瞎搅合...)

我没有么写:

[foo, bar, baz].to_json

而是:

[foo, bar, baz].map { |o| o.to_json }.to_json

然后反序列也一样... rofl.

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 14, 2019

[In reply to duangsuse::Echo]
回来了(因为身体素质真的开始有点 🌶🐔 了,而且非常需要休息,然后老是熬夜容易变丑,虽然其实长的就不咋地,大嘘),顺便添了一些任务

  1. 部署文档添加 Systemd 低端口权限配置提示(服务程序部署安全,这样如果我们的 upstream 有严重的,例如 RCE、可以拿 Shell 的安全问题别人不至于一下子迫真 rm -rf / 殃及池鱼) ✔️

  2. 把所有 Endpoint mapping 的 Int? 换成 java.lang.Integer? (要不然错误,说 int 不能是 optional 的,虽然本来有默认值 0)(这个打脸了,我真的不是不了解 Kotlin... 我真的只是被 Spring 的提示误导了... emmm) ✔️

  3. 为了 Clients 数据交换开心,添加 PATCH Json API(现在创建用户之后可以直接拿 JSON 去 patch 属性了,不用一个一个属性去 update) ✔️
    (现在还不是 RESTful 的)

  4. 添加用户和管理员权限验证的 Middleware(WebFilter)、其中用户的权限验证和 Rate Limit 一起做(GeekHits API 也一起开放了)

  5. 为 CI Intergation 添加 Node.JS 和 MRI Ruby 依赖,并且开始使用外围的 Spectrum Ruby 客户端接口测试(从 JUnit 启动服务器和 RSpec 客户端自动化测试程序) ✔️

GeekApk v1b 完成后可能有别的打算(包括 Android 客户端,不准喷我不会什么设计模式)(有些人不准喷我菜...)(虽然我有时候的确很菜,但我自己觉得我很有前途,嗯嗯。)

希望以后都是艳阳高照。冻死了天又黑...

@duangsuse
Copy link
Collaborator Author

下一步操作是 WebHooks(GeekPush)支持、Topics 等和 MessageHeader 的支持、包括工具的其他平台移植

@duangsuse
Copy link
Collaborator Author

duangsuse commented Feb 15, 2019

  • 完成 RSpec 外部测试代码基
  • 添加用户和管理员权限验证的 Middleware(WebFilter)、其中用户的权限验证和 Rate Limit 一起做
  • 完成 API 逻辑
  • 提供 QCL API
  • 解决 unused warning,为 Migrate 和 QCL 提供 Main 里的 entrance

== 晚点

  • Ruby 客户端和 CLI
  • JavaScript 客户端
  • Android API 客户端库
  • Add GET Views for non-GET APIs (debug view)
  • 部署到 geekapk.moe
  • geekapk.moe 的基本前端 sitemap 界面
  • 消息队列 GeekPush,算是 J2EE 一点免得别人说太 trivial

== 发布之后

  • MessageHeader 规范处理和 Topics
  • 重写工具、移植到 Windows 等平台(能移植的)
  • (GeekHits API 也一起开放了) GeekHits API

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
designment Designment errors for GeekApk help wanted Extra attention is needed v1♭ GeekApk first version wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

1 participant